2014-03-03 103 views
8

我在Unity IoC中实现动态加载和注册我的程序集。Unity无法解析基本依赖链

考虑到这些类:

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) { } 
} 

而且这种配置:

var assembly = Assembly.LoadFile(@"path\MyAsm.dll"); 
container.RegisterTypes(
    AllClasses.FromAssemblies(assembly), 
    WithMappings.FromAllInterfacesInSameAssembly, 
    WithName.Default, 
    WithLifetime.Transient); 

代码:

var c = container.Resolve(typeof(IC)); 

抛出:

类型 “Microsoft.Practices.Unity.ResolutionFailedException”第一次机会异常出现在 Microsoft.Practices.Unity.dll

附加信息:依赖解析失败,类型= “MyAsm.IC”,名称=“(无)”。

发生异常时:解决。

异常是:InvalidOperationException - 类型IC没有 可访问的构造函数。


在异常时,该容器是:

MyAsm.IC,(无)

上述所有代码都在相同的组件MyAsm进行。在调试中分析容器,Registrations属性列出了ABC到它们各自的接口以及它们自己的映射的正确集合。

任何想法?

SOLUTION

泰勒的回答后,我改变了:

var assembly = Assembly.LoadFile(@"path\MyAsm.dll"); 

var assembly = Assembly.LoadFrom(@"path\MyAsm.dll"); 

这解决了问题。 Assembly上的这两种方法具有相同的参数和相同的返回类型以及vary just slightly in behavior纯洁的邪恶

回答

5

我能够重现你得到的错误。

因此,您正在从文件Assembly.LoadFile(@"path\MyAsm.dll");加载程序集,然后解决硬引用类型container.Resolve(typeof(IC));。我相信这些类型来自两个不同的编译二进制文件。将@“path \ MyAsm.dll”中的二进制文件的类型加载到容器中,但是您试图从应用程序路径的bin目录中解析二进制文件的类型(引用的程序集CopyLocal设置为True)。

要么需要注册已经加载到应用程序域的引用二进制文件中的类型,要么需要使用反射来解析已加载二进制文件中的类型以找到类型。

var assembly = AppDomain.CurrentDomain.GetAssemblies(). 
       SingleOrDefault(asm => asm.GetName().Name == "MyAsm"); 
... 
var c = container.Resolve(typeof(IC)); 

- 或 -

var assembly = Assembly.LoadFile(@"path\MyAsm.dll"); 
... 
var c = container.Resolve(assembly.GetType("MyAsm.IC")); 
+1

给这名男子啤酒。一旦你知道这个问题,实际的解决方案更容易(见Q)... –

+0

哇,我没有意识到这种微妙的区别。感谢那! – TylerOhlsen

1

你可以试试这一点。

Debug -> Windows -> Exception Settings 

取消选中“公共语言运行时例外”,然后重试。

0

我如何通过映射接口和存储库上unity.config解决它

<alias alias="IUserRepository" type="pHAB.Repository.Contract.IUserRepository, pHAB.Repository" /> 



<alias alias="UserRepository" type="pHAB.Repository.UserRepository, pHAB.Repository" /> 

<container> 
<register type="IUserRepository" mapTo="UserRepository"/> 
</container>