2

Ich schreibe eine Anwendung (über eine ASP.NET-Web-API verfügbar gemacht), deren gesamter Zweck es ist, zwei Datenquellen zu konsumieren und die Ähnlichkeiten und Unterschiede aufzudecken. So hat die API die folgende Konfiguration:Einfacher Injektor mit Abhängigkeit von zwei Objekten, die dieselbe Schnittstelle implementieren

public class FooController : WebAPI 
{ 
    public FooController(IFooRepository repoFromSourceA, IFooRepository repoFromSourceB) 
    { 
     ... 
    } 
} 

Beibehaltung der Unterscheidung von denen einer der ist, die Quelle (Source A und SourceB kann nicht ausgetauscht werden) scheint zu verwenden container.RegisterCollection(..) unmöglich (oder sehr gefährlich) zu machen. Außerdem, da eine Klasse beide Implementierungen verbraucht, scheint Decorator nicht passend zu sein.

Wie würde ich dann diese Abhängigkeitsinjektion einrichten?

+0

Die wichtigste Frage, bevor jemand diese Frage beantworten kann, ist, was mit 'FooController' passieren würde, wenn die beiden Argumente (versehentlich) vertauscht werden. Wenn wir also 'neuen FooController (neues RepoB(), neues RepoA())' instanziieren (was kompilieren würde), würde 'FooController' noch immer korrekt funktionieren oder bricht es ab (eine Exception zum Beispiel auslösen)? – Steven

+0

Es würde nicht brechen (keine Ausnahmen ausgelöst), aber die API würde den Anrufer lügen. Einige der Anrufe haben das Format "gib mir Gegenstände, die in A existieren, aber nicht in B." Wenn sie ausgetauscht wurden, würde der Aufrufer Objekte (oder keine Objekte) zurück erhalten, aber das Ergebnis wäre fehlerhaft. –

Antwort

6

Die Frage, die Sie haben, ist eine sehr häufige Frage. Viele Entwickler haben damit zu kämpfen, wenn sie mit Dependency Injection beginnen. In diesem Zusammenhang ist es immer wichtig, herauszufinden, ob Sie die Liskov Substitution Principle (LSP) verletzen, denn wenn Sie dies tun, sollten Sie stattdessen zwei separate Schnittstellen verwenden. Vergiss nie: Eine Schnittstelle ist mehr als nur die Methodensignaturen. Es ist ein Vertrag darüber, wie sich die Implementierungen dieses Vertrags verhalten und was sie zurückgeben.

Ihr Kommentar scheint darauf hinzuweisen, dass Sie den LSP nicht verletzen, da deren Verhalten identisch ist und sie gegeneinander ausgetauscht werden können (dies könnte die Anwendung beschädigen, aber den Verbraucher nicht beschädigen).

Der Weg, dies in Simple Injector zu behandeln, ist context based injection mit den RegisterConditional Methoden. Zum Beispiel:

container.RegisterConditional<IFooRepository, FooRepoA>(
    c => c.Consumer.Target.Parameter.Name.Contains("SourceA")); 
container.RegisterConditional<IFooRepository, FooRepoB>(
    c => c.Consumer.Target.Parameter.Name.Contains("SourceB")); 

Hier wird die RegisterConditional Verfahren wird mit einem Prädikat zugeführt, der Parameter des Konstruktors der Verbraucher, wenn die Abhängigkeit in eingespritzt wird, hat einen Namen, der entweder „SourceA“ oder „SourceB“ enthält.

+0

Perfekt; das sieht genau so aus, wie ich es mir wünsche. Und ja, ich habe ein bisschen Angst davor, LSP zu verletzen, also überprüfe ich mehrmals, bevor ich nach Hilfe frage. –

Verwandte Themen