2017-05-05 8 views
-1

Warum alle DI-Frameworks vor dem Start der Anwendung alle Abhängigkeiten in Runtime prüfen? Warum, um dies in der Kompilierzeit nicht zu überprüfen, was sind Vorteile dafür?Abhängigkeitsinjektion in der Kompilierungszeit

Kann die Abhängigkeit in der bereitgestellten Anwendung geändert werden? Zum Beispiel, wenn die Anwendung gestartet wird, sendet sie eine Benachrichtigung per E-Mail, aber danach können wir ändern, um per SMS zu senden, ohne die Anwendung zu stoppen?

+0

Sie scheinen den Punkt bei der Verwendung eines DI-Frameworks verpasst zu haben ... Wenn Sie es zur Kompilierungszeit tun, dann sind Sie nur Ihre Abhängigkeiten hart-Verdrahtung, die nicht DI ist ... – Milney

+1

Ok, so können Sie die Abhängigkeit ändern in bereits implementierter Anwendung? – Romper

+0

Das ist ein Punkt ja. Es erlaubt Ihnen auch, verschiedene Implementierungen auf Basis anderer Informationen, die nur zur Laufzeit bekannt sind, bedingt zu registrieren ... Es macht auch die Wartung schwieriger ... – Milney

Antwort

2

DI-Container per Definition arbeiten mit Reflektion, was bedeutet Laufzeit Metadaten. Wenn Sie möchten, dass alles zur Kompilierungszeit überprüft wird, sollten Sie keinen DI-Container verwenden, sondern Ihre Abhängigkeiten manuell verdrahten. Die Anwendung von DI von Hand ist eine gängige Praxis, die Pure DI genannt wird.

aber können wir ändern, um über SMS zu senden, ohne Anwendung zu stoppen?

Sie scheinen zu erfordern, dass die Anwendung auf Konfigurationsänderungen reagiert, während sie weiterläuft. Es gibt übliche Muster, mit denen Sie dies erreichen können. Normalerweise möchten Sie das Komponentenobjektdiagramm der Anwendung (die Kette von Klassen, die Verhalten mit ihren Abhängigkeiten enthalten) einmal definieren. Obwohl Sie ein solches Diagramm pro Anforderung erstellen können, sollte sich die Form des Diagramms später nicht ändern. Stattdessen verwenden Sie Muster wie Proxy und Composite. Zum Beispiel unter Berücksichtigung der folgenden Schnittstelle und Implementierungen:

interface INotificationSender 
{ 
    void Send(string message); 
} 

class MailNotificationSender : INotificationSender { ... } 

class SmsNotificationSender : INotificationSender { ... } 

Wir einen Proxy definieren können, wie folgt:

class ConfigBasedNotificationSenderProxy : INotificationSender 
{ 
    private readonly INotificationSender mail; 
    private readonly INotificationSender sms; 

    public ConfigBasedNotificationSenderProxy(
     INotificationSender mail, INotificationSender sms) 
    { 
     this.mail = mail; 
     this.sms = sms; 
    } 

    public void Send(string message) 
    { 
     bool sendThroughMail = ReadFromConfgWhereToSendTo(); 
     var sender = sendThroughMail ? this.mail : this.sms; 
     sender.Send(message); 
    } 
} 

Sie können folgende Objektgraph beim Start der Anwendung bauen:

var sender = new ConfigBasedNotificationSenderProxy(
    new MailNotificationSender(...) 
    new SmsNotificationSender(...)); 

Sie kann dies auch mit einem DI-Container verdrahten oder per Hand machen (Pure DI). Wichtiger Punkt jedoch, den ich hier zu machen versuche, ist, dass, selbst wenn Sie ändern müssen, wie sich die Anwendung zur Laufzeit verhält, Sie Ihre Anwendung nicht neu verdrahten müssen. Sie sollten in der Lage sein, das Aufrufdiagramm zu ändern, das die Objektdiagramme der Anwendung mithilfe von Proxyimplementierungen durchläuft.

+0

Aktualisiert mit Informationen zum Ändern des Anwendungsverhaltens zur Laufzeit. – Steven

Verwandte Themen