2014-03-03 12 views
8

Ich implementiere das dynamische Laden und die Registrierung meiner Assemblys in Unity IoC.Unity kann die grundlegende Abhängigkeitskette nicht auflösen

Unter diesen Klassen:

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

Und diese Konfiguration:

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

Der Code:

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

Würfe:

Eine erste Chance Ausnahme des Typs 'Microsoft.Practices.Unity.ResolutionFailedException' aufgetreten in Microsoft.Practices.Unity.dll

Zusätzliche Informationen: Auflösung der Abhängigkeit ist fehlgeschlagen, type = "MyAsm.IC", name = "(keine)".

Ausnahme aufgetreten während: während der Auflösung.

Ausnahme ist: InvalidOperationException - Der Typ IC keine zugänglich Konstruktor hat.


Zum Zeitpunkt der Ausnahme, war der Behälter:

MyAsm.IC, (none)

Alle obigen Code wird in der gleichen Baugruppe MyAsm durchgeführt. Beim Analysieren des Containers im Debug gibt die Registrations-Eigenschaft eine Auflistung der Zuordnungen von A, B und C zu ihren jeweiligen Schnittstellen sowie zu ihnen selbst.

Irgendwelche Ideen?

SOLUTION

Nach Tylers Antwort, die ich geändert:

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

zu

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

die das Problem gelöst. Diese beiden Methoden auf Assembly haben dasselbe Argument und denselben Rückgabetyp und vary just slightly in behavior. Pure bösen.

Antwort

5

Ich konnte den Fehler reproduzieren, den Sie erhalten.

So laden Sie die Baugruppe aus einer Datei Assembly.LoadFile(@"path\MyAsm.dll");, und Sie lösen dann einen hart referenzierten Typ container.Resolve(typeof(IC));. Ich glaube, dass diese Typen von zwei verschiedenen kompilierten Binärdateien kommen. Die Typen aus der Binärdatei in @ "path \ MyAsm.dll" werden in den Container geladen, aber Sie versuchen, den Typ der Binärdatei aus dem bin-Verzeichnis des Anwendungspfads zu ermitteln (Die referenzierte Assembly CopyLocal ist auf True gesetzt).

Entweder müssen Sie die Typen aus der referenzierten Binärdatei registrieren, die bereits in der Anwendungsdomäne geladen ist, oder Sie müssen den Typ aus der geladenen Binärdatei mithilfe der Reflektion auflösen, um den Typ zu finden.

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

--oder--

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

diesem Mann gibt ein Bier. Die eigentliche Lösung ist noch einfacher (siehe Q), sobald Sie das Problem kennen ... –

+0

Wow, ich war mir dieser feinen Unterscheidung nicht bewusst. Dank dafür! – TylerOhlsen

1

du auch versuchen können.

Debug -> Windows -> Exception Settings 

Deaktivieren Sie "Common Language Runtime Ausnahmen" und versuchen Sie es erneut.

0

Wie ich löse es durch die Interface-Mapping und Repositories auf 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> 
Verwandte Themen