none
Serialization + AssemblyResolver + in-memory assembly = EPIC FAIL! RRS feed

  • Question

  • Hi folks, got a weird problem here. I have a .Net 2.0 targeted app which embeds assemblies as embedded resources.  These are loaded dynamically into memory directly using AssemblyResolver.  Some of these assemblies use serialization to load/save XML configuration files.

    The problem is any plugin assemblies which perform serialization / deserialization in this manner fail in doing so, apparently because the assemblies aren't actually stored on the disk.  Here is the exception: 

    Attempting to resolve assembly: launcher.XmlSerializers, Version=0.8.0.0, Culture=neutral, PublicKeyToken=null
    System.InvalidOperationException: Unable to generate a temporary class (result=1).
    error CS0012: The type 'Amp.Configuration.BaseConfiguration' is defined in an assembly that is not referenced. You must add a reference to assembly 'AmpCore, Version=0.8.0.0, Culture=neutral, PublicKeyToken=null'.
    
       at System.Xml.Serialization.Compiler.Compile(Assembly parent, String ns, XmlSerializerCompilerParameters xmlParameters, Evidence evidence)
       at System.Xml.Serialization.TempAssembly.GenerateAssembly(XmlMapping[] xmlMappings, Type[] types, String defaultNamespace, Evidence evidence, XmlSerializerCompilerParameters parameters, Assembly assembly, Hashtable assemblies)
       at System.Xml.Serialization.TempAssembly..ctor(XmlMapping[] xmlMappings, Type[] types, String defaultNamespace, String location, Evidence evidence)
     A first chance exception of type 'System.NullReferenceException' occurred in launcher.exe
      at System.Xml.Serialization.XmlSerializer.GenerateTempAssembly(XmlMapping xmlMapping, Type type, String defaultNamespace)
       at System.Xml.Serialization.XmlSerializer..ctor(Type type, String defaultNamespace)
       at Amp.Configuration.ConfigurationIO`1.Save(T config, String filepath)
    Inner Exception:
    none

    Seriously?   You *must* deserialize a type that is stored on a drive?!?   My understanding from another thread is that this limitation is fixed in .Net 4.0, but that is not an option for me.

    I can fix this by writing the assemblies to TEMP and using LoadFrom(tempfile) instead of Load(buffer).  But I really don't want to do that.  Other than this serialization/deserialization issue, everything works great loading the assemblies directly from memory.

    Is there another work-around that  will allow me to keep targeting .net 2.0 and get serialization to work without writing the assemblies to the drive?  That is what I am currently doing as a temporary workaround.

    The other option is to refactor how these config files work and don't use serialization.  I'll probably go that route if I can't find another good long-term solution to make this work.

    Thanks in advance for any help on this...


    Thursday, November 7, 2013 2:30 PM

Answers

  • Hi,

    I think we should try your second solution:
    The other option is to refactor how these config files work and don't use serialization.  I'll probably go that route if I can't find another good long-term solution to make this work.

    Because as you said that we deserialize a type that is stored on a drive.

    XML Serialisation works by generating code to perform the serialisation. This is done in a temporary assembly created for that purpose the first time it is needed.

    However this relies on being able to write the assembly to disk.<sup>1</sup>

    Your options are either to (1) given the user account which is running the process write permission (for an ASP.NET application this is likely to be a bad idea). (2) Use the SDK tool (sgen.exe) to pre-generate (at development/compile time) the serialisation assembly, and then use (and deplot) that assembly

    Friday, November 8, 2013 6:34 AM