2017-01-24 6 views
0

Ich bekomme eine DependencyResolutionException versuchen, Autofac parameterized instantiation zu verwenden, um eine indirekte Abhängigkeit aufzulösen.Indirekte parametrisierte Instanziierung mit Autofac

Angenommen, ich habe die folgenden Klassen:

public interface IMuffin {} 

public class Muffin : IMuffin 
{ 
    public Muffin(IButter butter) {} 
} 

public interface IButter {} 

public class Butter : IButter 
{ 
    public Butter(IKnife knife) {} 
} 

public interface IKnife {} 

Jetzt nehme ich ein IMuffin wollen, aber ich will die IKnife Abhängigkeit als Parameter liefern, wie folgt aus:

public class Breakfast 
{ 
    public Breakfast(Func<IKnife, IMuffin> muffinFactory) 
    { 
     var muffin = muffinFactory(new Knife()); 
    } 

    private class Knife : IKnife {} 
} 

Das Problem ist, Ich bekomme eine Ausnahme auf muffinFactory(new Knife()) Beschwerde, dass die Fabrik die IKnife Abhängigkeit des Butter Konstruktors mit den verfügbaren Parametern und Diensten nicht lösen kann. Dies macht keinen Sinn, da ich eine Instanz von IKnife als Parameter für die Fabrik zur Verfügung gestellt habe.

Dies scheint wie es sollte funktionieren. Was vermisse ich?

+0

Dies ist [eine FAQ in der Dokumentation adressierte] (http://autofac.readthedocs.io/en/latest/faq/injecting-global -Parameter.html). –

+0

Okay, ich kann sehen, woher sie kommen, aber die Verwendung der parametrisierten Instanziierung für gerade _direct_ Abhängigkeiten beinhaltet etwas "Wissen". Und es bedarf nur eines kleinen Refactorings, um eine direkte Abhängigkeit in eine indirekte umzuwandeln. Genau das ist in meinem Fall passiert. Verwenden Sie das obige Beispiel und nehmen Sie an, dass 'Muffin' ursprünglich direkt von' IKnife' abhing, so dass die parametrisierte Instanziierung durch 'Breakfast' funktionieren würde. Als "Butter" ausgeklammert wurde, wurde "Iknife" zu einer indirekten Abhängigkeit, die "Breakfast" brach. "IMuffin" -Kunden sollten von einer solchen Änderung nicht betroffen sein. –

Antwort

0

Die Fabrik in Ihrem Beispiel ist eine Fabrik für IMuffin und die IKnife Parameter wird als typed parameter übergeben. Ihre Klasse Muffin benötigt jedoch keine IKnife Instanz. Es erfordert eine IButter Instanz. Die IKnife Instanz wird von der Klasse Butter benötigt. Der Parameter, den Sie an die Factory übergeben haben, kann jedoch nur zum Erstellen einer Muffin Instanz verwendet werden und wird nicht zum Auflösen einer Abhängigkeit von Muffin verwendet. Der korrekte Typ Ihres muffinFactory wäre Func<IButter, IMuffin>.

Um Ihr Beispiel Arbeit, die Sie brauchen zwei Fabriken zu machen:

public class Breakfast 
{ 
    public Breakfast(Func<IKnife, IButter> butterFactory, Func<IButter, IMuffin> muffinFactory) 
    { 
     var butter = butterFactory(new Knife()); 
     var muffin = muffinFactory(butter); 
    } 

    private class Knife : IKnife { } 
} 
+0

Ja, ich habe diesen Ansatz nach dem Posten versucht. Da Autofac jedoch eine Abhängigkeitsbaumstruktur durchlaufen kann, scheint es, als ob es in der Lage sein sollte, die von Ihnen angegebenen Parameter mitzunehmen, um alle Abhängigkeiten aufzulösen, nicht nur die der obersten Ebene. Enttäuscht, dass ich es in der Hand halten muss, um die "IKnife" auf der zweiten Ebene verfügbar zu machen. –

+0

Es nimmt absichtlich nicht Parameter von der obersten Ebene und übergibt sie an jede Auflösung über den gesamten Stapel. [Siehe die FAQ.] (Http://autofac.readthedocs.io/en/latest/faq/injecting-global-parameters.html) –

+0

@TravisIllig, danke für den Link - das hilft! Bitte sehen Sie meine Antwort auf die ursprüngliche Frage. –