2014-03-03 156 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>