You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Enable compilation of WindowsForms applications that use non-primitive resources on .NETCore. Avoid creating live objects when building resources for non-primitive types. Set a path moving forward to avoid using BinaryFormatter.
This can be done by passing through pre-serialized data from resx to resources file.
options: 1 vs 2 assemblies? I've tried both. 1 is easier for maintenance and testing. Dependencies of the reader are the same as writer. Size of writer is 23KB, reader is 46KB.
naming:
System.ComponentModel.Resources
System.Resources.Serialization
System.Resources.PassThrough
System.Resources.Extensions
System.Resources.Data
System.Resources.Binary
Types:
Nouns: ResourceReader, ResourceSet, and ResourceWriter
Prefixes:
Serializing
PassThrough
Data
Object
Component
Converting
Preserialized
Deserializing
Proposed API
// optionally sealed if we don't want extensibilitypublicpartialclassDeserializingResourceReader: System.Resources.IResourceReader
{// all of these are present on ResourceReaderpublicDeserializingResourceReader(System.IO.Stream stream){}publicDeserializingResourceReader(stringfileName){}publicvoidClose(){}publicvoidDispose(){}public System.Collections.IDictionaryEnumerator GetEnumerator(){thrownull;}publicvoidGetResourceData(stringresourceName,outstringresourceType,outbyte[]resourceData){thrownull;}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator(){thrownull;}// Optional additions if we want to support extensibilityprotectedvirtualintVersion{get{thrownull;}}protectedvirtualobjectDeserializeObject(System.IO.BinaryReader reader,Typetype){thrownull;}}// optionally sealed if we don't want extensibilitypublicpartialclassPreserializedResourceWriter: System.Resources.IResourceWriter
{// all of these are present on ResourceWriterpublicPreserializedResourceWriter(System.IO.Stream stream){}publicPreserializedResourceWriter(stringfileName){}public System.Func<System.Type,string> TypeNameConverter {get{thrownull;}set{}}publicvoidAddResource(stringname,byte[]value){}publicvoidAddResource(stringname, System.IO.Stream value){}publicvoidAddResource(stringname, System.IO.Stream value,boolcloseAfterWrite){}publicvoidAddResource(stringname,objectvalue){}publicvoidAddResource(stringname,stringvalue){}// existing pass through member that doesn't encode any deserialization formatpublicvoidAddResourceData(stringname,stringtypeName,byte[]serializedData){}publicvoidClose(){}publicvoidDispose(){}publicvoidGenerate(){}// Optional additions if we want to support extensibilityprotectedvirtualstringResourceReaderTypeName{get{thrownull;}}protectedvirtualstringResourceSetTypeName{get{thrownull;}}protectedvoidAddResourceData(stringname,stringtypeName,objectdataContext){}protectedvirtualvoidWriteData(System.IO.BinaryWriter writer,objectdataContext){}// Below are new methods that behave similarly to AddResourceData but imply a different form // of pre-serialized data.// Similar to AddResourceData but encodes deserialization format, necessary to distinguish// between pure pass-through case. publicvoidAddBinaryFormattedResourceData(stringname,stringtypeName,byte[]value){}// Data is wrapped in a stream and passed to Activator.CreateInstance// This is what gets used by ResXFileRef in resx.publicvoidAddStreamResourceData(stringname,stringtypeName,byte[]value){}publicvoidAddStreamResourceData(stringname,stringtypeName, System.IO.Stream value,boolcloseAfterWrite){}// Data is passed to typeconverter as either byte[] or string respectivelypublicvoidAddTypeConverterResourceData(stringname,stringtypeName,byte[]value){}publicvoidAddTypeConverterResourceData(stringname,stringtypeName,stringvalue){}}// not shown internal class RuntimeResourceSet
Alternatives
expand
Extend ResourceReader/Writer
Types are frozen in existing frameworks - won't work for MSBuild which needs to run on desktop.
Doesn't solve the problem for existing frameworks, which MSBuild needs to support
Essentially imagine the API in this proposal on the existing types instead of new types.
Same issues as option 1.
Requires a revision to resources format or some convention for defining serialization methods.
Wrap ResourceReader/Writer and .resources format
Requires same API as this proposal, but doesn't copy as much code.
Implementation & payload size will be less efficient due to wrapping
Extend only ResourceSet
Still requires Writer API, though one could imagine building this only using ResourceWriter.AddResourceData if you were able to change the ResourceSet name in the generated resources or get the designer to pass it in.
Without a matching Reader is much less efficient than RuntimeResourceSet due to lookup methods being internal. Once you add a ResourceReader it's effectively the same as the proposal, but places deserialization in ResourceSet instead of the Reader.
This really exposes a gap in the IResourceReader / ResourceReader abstraction. If lookup strategy must be implemented for reasonable perf, then we should update the abstractions. One could consider this as our opportunity to do that, using the unsealed virtual Reader as the new abstraction.
// previously sealedpublicclassResourceReader: System.Resources.IResourceReader
{// new protectedvirtualintVersion{get{thrownull;}}protectedvirtualobjectDeserializeObject(System.IO.BinaryReader reader,Typetype){thrownull;}}
In addition to these API additions, we need to make RuntimeResourceSet usable for derived ResourceReaders by adding a IResourceReader constructor that can upcast to a ResourceReader to give lookup-behavior. For the current scenarios we don't need it to be made public / unsealed, but it could be.
internalclassRuntimeResourceSet{// new internalRuntimeResourceSet(IResourceReaderreader){}// if reader is ResourceReader, will do lazy loading.}
The text was updated successfully, but these errors were encountered:
ericstj
changed the title
[Draft] System.Resources API additions for non-primitive objects
System.Resources API additions for non-primitive objects
Apr 22, 2019
TypeNameConverter isn't used by MSBuild, the only case this was used on ResourceWriter in the framework was for multitargeting by System.Web. Since we aren't looking to plumb this writer to System.Web we can leave that out.
GetResourceData on the reader is and AddResourceData on the writer both provide raw access to the binary data on representing the types. We can decide not to expose these as we don't have a scenario for it. They were used originally by loc tooling that operated on .resources rather than source resx. Let's leave these off until we have a scenario for it.
We also mentioned that AddStreamResourceData can be changed to AddActivatorResourceData and only take a stream (so that the method signature indicates the primitive type passed to Activator, similar to what we're doing with AddTypeConverterResourceData).
Goals
Enable compilation of WindowsForms applications that use non-primitive resources on .NETCore. Avoid creating live objects when building resources for non-primitive types. Set a path moving forward to avoid using BinaryFormatter.
This can be done by passing through pre-serialized data from resx to resources file.
Draft Implementation : dotnet/corefx#36906
Naming pivots
Assembly / Namespace : System.Resources.Extensions
Types:
Proposed API
Alternatives
expand
Extend ResourceReader/Writer
Build into ResourceReader/Writer
Wrap ResourceReader/Writer and .resources format
Extend only ResourceSet
Details
If we change inbox types and can constrain runtime to only .NETCoreApp 3.0 we would do the following.
dotnet/corefx@bbb08de#diff-9a2d6c26f251ad72e355afb8bcb72ca2L18
dotnet/corefx@bbb08de#diff-147dad3b8d1fabfe7d53faa577442011L69
In addition to these API additions, we need to make RuntimeResourceSet usable for derived ResourceReaders by adding a IResourceReader constructor that can upcast to a ResourceReader to give lookup-behavior. For the current scenarios we don't need it to be made public / unsealed, but it could be.
The text was updated successfully, but these errors were encountered: