locked
Binary Serialization behavior differs with Enterprise Library installed RRS feed

  • Question

  • I developed an application with VS2005/.Net 2.0 that saves off a large Dictionary<string, MyClass> to disk using the binary serializer. MyClass is quite complex, and also contained Dictionary<string, OtherClasses> as private members. Everything worked great, I could deserialize the same file even with later built versions of my dll.

    Then I moved to a different development machine and deserializing stopped working. Even after re-generating the serialized files on this machine, deserialization would fail, complaining that it either couldn't find MyAssembly (which was nuts because that was the current running assembly), or more frequently with

    Unable to load type System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[MyNamespace.MyClass, MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] required for deserialization.

    After carefully examining the loaded dlls on both of these machines, I noted that on the original machine I had Enterprise Library 3.1 - May 2007 loaded. On the new machine, I did not.

    I installed Enterprise Library 3.1 on the new machine, and indeed the deserialize started working again. I am not utilizing any of the EL functionality (that I know of).

    How and why is this happening???

    I attempted to write a reproduction using a very simple Dictionary<string, MyClass>, where MyClass is not so complex, but the problem does not occur.

    -Ben
    Thursday, September 11, 2008 8:31 PM

Answers

  • You might try adding the event handlers as early as possible: the static constructor for your entry point (public static void Main(string[] args)) class.


    But, fundamentally, if Enterprise Library is the only thing that's different, it sounds like an Enterprise Library-related issue and you'll need to ask on their forums / support. http://www.codeplex.com/entlib 


    John Lambert - JLamb - Microsoft
    Monday, September 15, 2008 10:06 PM
    Moderator

All replies

  • From what you describe, it sounds like a dependency issue -- probably in a DLL that you're not using directly. If you don't want to post the entire class in the public forums, you can submit it in a bug report and mark it as "Private" via https://connect.microsoft.com/VisualStudio .

    Otherwise, this code might help you debug:
            static Program()  
            {  
                AppDomain.CurrentDomain.AssemblyLoad += new AssemblyLoadEventHandler(CurrentDomain_AssemblyLoad);  
                AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);  
                AppDomain.CurrentDomain.TypeResolve += new ResolveEventHandler(CurrentDomain_TypeResolve);  
            }  
     
            static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)  
            {  
                Console.WriteLine("AssemblyResolve {0}", args.Name);  
                Console.WriteLine(new StackTrace(true));  
                return null;  
            }  
     
            static void CurrentDomain_AssemblyLoad(object sender, AssemblyLoadEventArgs args)  
            {  
                Console.WriteLine("AssemblyLoad {0}", args.LoadedAssembly.FullName);  
                Console.WriteLine(new StackTrace(true));  
            }  
     
            static System.Reflection.Assembly CurrentDomain_TypeResolve(object sender, ResolveEventArgs args)  
            {  
                Console.WriteLine("TypeResolve {0}", args.Name);  
                Console.WriteLine(new StackTrace(true));  
                return null;  
            }  
     

    John Lambert - JLamb - Microsoft
    Friday, September 12, 2008 9:44 PM
    Moderator
  • I added the event handlers just before my call to deserialize, and then recorded the stack trace when CurrentDomain_AssemblyResolve was called for MyAssembly.  I then installed Enterprise Library 3.1 and repeated the procedure. Guess what?? CurrentDomain_AssemblyResolve doesn't get called for MyAssembly, which would imply that it was already loaded some time before I hooked in the event handlers. Does that give you any insight??

    -Ben
    Monday, September 15, 2008 8:32 PM
  • You might try adding the event handlers as early as possible: the static constructor for your entry point (public static void Main(string[] args)) class.


    But, fundamentally, if Enterprise Library is the only thing that's different, it sounds like an Enterprise Library-related issue and you'll need to ask on their forums / support. http://www.codeplex.com/entlib 


    John Lambert - JLamb - Microsoft
    Monday, September 15, 2008 10:06 PM
    Moderator
  • Yes, I would agree that it is an Enterprise Library issue if the presence of Enterprise Library was CAUSING the problem, instead of FIXING a problem I didn't know I had.

    One other thing I should point out. The software I am developing is a Visual Studio Add-In, not a standalone executable.

    Anyway, after playing some more with the AssemblyResolve event, I came up with something that actually fixes the problem, but it scares me.

           System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) 
           { 
              if (args.Name.StartsWith("MyAssembly")) 
              { 
                 return this.GetType().Assembly; 
              } 
              return null
           } 

    I'm not sure this is safe, but it does only get called once, and solves the problem for the duration of the runtime. But I really shouldn't have to do that.

    -Ben
    Monday, September 15, 2008 10:44 PM
  • For those of you following the discussion, somebody in the EL forum was able to confirm that having EL installed causes VS to more eagerly resolve assemblies, and also explained what was going on, which ended up being a common problem of anything that has a "plug-in" architecture, due to Load/LoadFrom context differences.

    Here's the rest of the discussion:
    http://www.codeplex.com/entlib/Thread/View.aspx?ThreadId=35713

    John, thanks for your help.

    -Ben



    Wednesday, September 17, 2008 9:07 PM