ipjohnson / Grace

Grace is a feature rich dependency injection container library
MIT License
336 stars 33 forks source link

TypeInitializationException when scanning for assemblies #179

Closed davidkeaveny closed 5 years ago

davidkeaveny commented 6 years ago

Maybe I'm just tired and had enough of banging my head against .NET's assembly loading code, but I cannot get the following code to run:

   var dataLayerDll = Path.Combine(Environment.CurrentDirectory, "MyProject.DataLayer.dll");
   var businessLayerDll = Path.Combine(Environment.CurrentDirectory, "MyProject.BusinessLayer.dll");

   try
   {
       container.Configure(grace =>
                   {
                       grace.Export(Types.FromAssembly(dataLayerDll)).ByInterfaces();
                       grace.Export(Types.FromAssembly(businessLayerDll)).ByType();
                       grace.Export(Types.FromAssembly(businessLayerDll)).ByInterfaces();
                   });

   }
   catch (ReflectionTypeLoadException ex)
   {
       foreach (var lex in ex.LoaderExceptions)
       {
           Log.Error(lex.Message);
       }

       throw;
   }

Instead, it throws a TypeInitializationException, which is complaining about loading Grace 4.0.2 (which is the version that Grace.Net links to, although I am running Grace 6.4.0). I've tried adding an assembly binding redirect for Grace to 6.4.0 but to no avail.

My Fusion log appears below:

Assembly manager loaded from: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll Running under executable D:\Bit\MyProject.TaskRunner\bin\Debug\MyProject.TaskRunner.exe --- A detailed error log follows.

=== Pre-bind state information ---> LOG: DisplayName = Grace, Version=4.0.2.0, Culture=neutral, PublicKeyToken=null (Fully-specified) LOG: Appbase = file:///D:/Bit/MyProject.TaskRunner/bin/Debug/ LOG: Initial PrivatePath = NULL Calling assembly : Grace.Net, Version=4.0.2.0, Culture=neutral, PublicKeyToken=null.

LOG: This bind starts in default load context. LOG: Using application configuration file: D:\Bit\MyProject.TaskRunner\bin\Debug\MyProject.TaskRunner.exe.Config LOG: Using host configuration file: LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config. LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind). LOG: Attempting download of new URL file:///D:/Bit/MyProject.TaskRunner/bin/Debug/Grace.DLL. WRN: Comparing the assembly name resulted in the mismatch: PUBLIC KEY TOKEN ERR: Failed to complete setup of assembly (hr = 0x80131040). Probing terminated.

Cracking open the assemblies in dotPeek, Grace 6.4.0 has a public key token (b7d24c6367970497) while the reference held by Grace.Net has a public key token of null. Is there something I'm missing?

P.S. This is built and run under .NET Framework 4.7.2 on Windows 10 Professional.

ipjohnson commented 6 years ago

@davidkeaveny you aren't missing anything I started signing Grace a while back and it makes it incompatible with some of the older side libraries like Grace.Net. That said now that .netstandard 2.0 support Assembly.Load I can upgrade Grace.Net to both standard and .net 4.5.

For the moment you can probably just copy the methods from here and I can put together something in the coming days.

ipjohnson commented 6 years ago

@davidkeaveny So I took a look at the Grace.Net library last night and everything other than the Types static class is related to System.Configuration.

I think what I'm going to do is create a documentation section for this and put the class their and you can just add it directly to your project. The reality is they are just simple wrappers around Assembly.Load and don't require their own libraries.

Does that seem like a reasonable solution?

ipjohnson commented 5 years ago

Never heard back so I'm marking as closed