2017-11-03 5 views
4

In einigen IoC-Containern können Argumente im Konstruktor vorhanden sein, die vom Container nicht erfüllt werden können. Ist dies mit den Bibliotheken Microsoft.Extensions.DependencyInjection und IServiceProvider möglich? Wenn nicht, was ist eine saubere Lösung für diese Art von Problem?Optionale Konstruktorinjektionsargumente mit .NET Core

Zum Beispiel:

class InContainer 
{ 
    public InContainer(NotInContainer dependency) { ... } 
} 

class Consumer 
{ 
    public Consumer(IServiceProvider serviceProvider) 
    { 
     NotInContainer currentDependency = ... // from some other source 
     // passing the anonymous object here is not supported, 
     // but I would like to 
     InContainer = serviceProvider.GetService<InContainer>(
      new { dependency = currentDependency } 
     ); 
    } 
} 
+0

Meinst du während der Registrierung oder pro Instanz? –

Antwort

2

Normalerweise erstelle ich in diesem Fall eine Fabrik von Hand.

public class TheFactory 
{ 
    public TheFactory(SomeType fromContainer) 
    { 
     _fromContainer = fromContainer; 
    } 

    public IProduct Create(SomeOtherType notFromContainer) => new TheProduct(_fromContainer, notFromContainer); 

    private readonly SomeType _fromContainer; 

    private class TheProduct : IProduct 
    { 
     // ... 
    } 
} 

Wenn Sie pro-Produkt benötigen Abhängigkeiten aus dem Behälter, Create die Fabrik hat sie zu lösen. Oder im Fall von z.B. Einheit, erhält die Fabrik eine Func aus dem Container.

+0

Ich nehme an, dann könnte die Fabrik irgendwelche IDisposable's verfolgen und sie aufräumen. –

+0

Es muss wahrscheinlich nicht einmal, da Sie einen Aufruf von 'Create' auf die gleiche Weise wie' new' behandeln, es erstellt eine Instanz, die dem Aufrufer gehört. – Haukinger

0

In Ihrem Beispiel bieten Sie die serviceProvider mit einem LaufzeitwertcurrentDependency. Anwendungskomponenten sollten während der Erstellung keine Laufzeitdaten benötigen, wie in here erläutert. Die Lösung besteht darin, Ihr Design zu refaktorieren, wie in diesem Artikel erläutert.

Über optionale Argumente:

Die Tatsache, dass einige DI Container optionale Argumente unterstützen, ist es keine gute Praxis machen, sie zu nutzen. In der Tat sollten Injection-Konstruktorargumente niemals optional sein.

Wie in this Artikel:

Eine optionale Abhängigkeit bedeutet, dass der Hinweis auf die Abhängigkeit null sein wird, wenn es nicht im Lieferumfang enthalten ist. Nullreferenzen komplizieren Code, weil sie eine spezifische Logik für den Nullfall erfordern. Anstatt eine Nullreferenz zu übergeben, könnte der Aufrufer eine Implementierung ohne Verhalten einfügen, d. H. Eine Implementierung des Null-Objektmusters.

Wenn nicht, was ist eine saubere Lösung für diese Art von Problem?

Wie bereits erwähnt, die Null Object pattern ist die Lösung für diese, auch wenn eine DI-Container verwenden, die tatsächlich optional Konstruktor Abhängigkeiten unterstützt.

+0

Die OP-Abhängigkeit ist jedoch nicht optional. Es ist einfach nicht im Container vorhanden und er möchte es zur Zeit der Lösung bereitstellen. – Evk

+0

@Evk: Mein Update hat deinen Kommentar durchgestrichen. – Steven

+0

Ja, das macht Sinn, aber der erste Teil Ihrer Antwort scheint für die Frage nicht relevant zu sein. – Evk