I'm implementing dynamic loading and registration of my assemblies in Unity IoC.
Given these classes:
public interface IA { }
public interface IB { }
public interface IC { }
public class A : IA { }
public class B : IB
{
public B(IA a) { }
}
public class C : IC
{
public C(IB b) { }
}
And this configuration:
var assembly = Assembly.LoadFile(@"path\MyAsm.dll");
container.RegisterTypes(
AllClasses.FromAssemblies(assembly),
WithMappings.FromAllInterfacesInSameAssembly,
WithName.Default,
WithLifetime.Transient);
The code:
var c = container.Resolve(typeof(IC));
Throws:
A first chance exception of type 'Microsoft.Practices.Unity.ResolutionFailedException' occurred in Microsoft.Practices.Unity.dll
Additional information: Resolution of the dependency failed, type = "MyAsm.IC", name = "(none)".
Exception occurred while: while resolving.
Exception is: InvalidOperationException - The type IC does not have an accessible constructor.
At the time of the exception, the container was:
MyAsm.IC,(none)
All of the above code is performed in the same assembly MyAsm. Analyzing the container in debug, the Registrations
property lists what seems to be proper collection of mappings of A
, B
and C
to their respective interfaces as well as themselves.
Any ideas?
SOLUTION
After Tyler's response I changed:
var assembly = Assembly.LoadFile(@"path\MyAsm.dll");
to
var assembly = Assembly.LoadFrom(@"path\MyAsm.dll");
which solved the issue. These two methods on Assembly
have same argument and same return type and vary just slightly in behavior. Pure evil.
I was able to reproduce the error you are getting.
So you are loading the assembly from a file Assembly.LoadFile(@"path\MyAsm.dll");
, and then you are resolving a hard referenced type container.Resolve(typeof(IC));
. I believe those types are coming from two different compiled binaries. The types from the binary in @"path\MyAsm.dll" are loaded into the container, but you are attempting to resolve the type of the binary from your application path's bin directory (Referenced assembly CopyLocal is set to True).
Either you need to register the types from the referenced binary that is already loaded in the app domain or you need to resolve the type from the loaded binary using reflection to find the type.
var assembly = AppDomain.CurrentDomain.GetAssemblies().
SingleOrDefault(asm => asm.GetName().Name == "MyAsm");
...
var c = container.Resolve(typeof(IC));
--or--
var assembly = Assembly.LoadFile(@"path\MyAsm.dll");
...
var c = container.Resolve(assembly.GetType("MyAsm.IC"));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With