14 Stimmen

Alternativen zur Dependency Injection

Ich bin auf Depency Injektion suchen, kann ich die Vorteile sehen, aber ich habe Probleme mit der Syntax, die es erstellt. Ich habe dieses Beispiel

public class BusinessProducts
{
   IDataContext _dx;

   BusinessProducts(IDataContext dx)
   {
      _dx = dx;
   }

   public List<Product> GetProducts()
   {
    return dx.GetProducts();
   }
}

Das Problem ist, dass ich nicht schreiben will

BusinessProducts bp = new BusinessProducts(dataContextImplementation);

Ich würde weiter schreiben

BusinessProducts bp = new BusinessProducts();

weil ich finde, dass sich die erste Alternative einfach unnatürlich anfühlt. Ich möchte nicht wissen, wovon das BusinessProduct "abhängt", um die Produkte zu erhalten, außerdem habe ich das Gefühl, dass mein Code dadurch unleserlicher wird.

Gibt es irgendwelche Alternativen zu diesem Ansatz, wie ich meine ursprüngliche Syntax für die Erstellung von Objekten behalten möchte, aber ich möchte noch in der Lage sein, die Abhängigkeiten zu fälschen, wenn Unit-Tests oder ist es diese Abhängigkeit Injektion Frameworks für mich tun können?

Ich programmiere in c#, aber Alternativen aus anderen Sprachen sind willkommen

10voto

tvanfosson Punkte 506878

Ich verwende eine Fabrik für meinen Kontext und injiziere sie, wobei ich einen geeigneten Standard bereitstelle, wenn die bereitgestellte Fabrik null ist. Ich tue dies aus zwei Gründen. Erstens verwende ich den Datenkontext als eine Einheit der Arbeit skalierte Objekt, so dass ich in der Lage sein muss, sie zu erstellen, wenn benötigt, nicht halten Sie eine um. Zweitens bin ich in erster Linie mit DI, um die Testbarkeit zu erhöhen, mit Entkopplung nur eine sekundäre Überlegung.

Meine Klasse für Geschäftsprodukte würde also wie folgt aussehen:

public class BusinessProducts
{
     private IDataContextFactory DataContextFactory { get; set; }  // my interface

     public BusinessProducts() : this(null) {}

     public BusinessProducts( IDataContextFactory factory )
     {
          this.DataContext = factory ?? new BusinessProductsDataContextFactory();
     }

     public void DoSomething()
     {
          using (DataContext dc = this.DataContextFactory().CreateDataContext())
          {
             ...
          }
     }

Eine Alternative dazu wäre, die Eigenschaft "factory" öffentlich einstellbar zu machen und eine alternative Fabrik durch Einstellen der Eigenschaft zu injizieren. So oder so, wenn Sie den Null-Konstruktor beibehalten wollen, müssen Sie einen Standard bereitstellen.

6voto

troelskn Punkte 110542

Sie können eine Fabrik gründen. DI-Container eignen sich am besten für Verdrahtungen, die zur Einrichtungszeit erfolgen - nicht zur Laufzeit (wie es hier der Fall zu sein scheint). Fabriken können auf unterschiedliche Weise implementiert werden, je nachdem, wie steckbar sie sein müssen und an wie vielen Stellen sie verwendet werden sollen.

6voto

Owen Punkte 6875

Ich würde normalerweise einen leeren Konstruktor haben, der eine feste Instanz (oder eine von IoC erstellte Instanz) verwendet, und einen mit DI, d.h..

public class BusinessProducts
{
   IDataContext _dx;

   BusinessProducts()
   {
      _dx = new SolidDataContext();
   }

   BusinessProducts(IDataContext dx)
   {
      _dx = dx;
   }
}

Auf diese Weise können Sie DI verwenden, um die Standardinstanz bei Unit-Tests zu überschreiben.

4voto

Bryan Watts Punkte 43539

Ihre Gefühle sind zwar berechtigt, aber unangebracht.

En Injektion von Abhängigkeiten Muster ist eine direkte Anwendung des Umkehrung der Kontrolle Prinzip.

Das bedeutet, dass Ihre Klasse nicht mehr die Instanzen anderer Klassen kontrolliert, die sie konsumiert, sondern dass diese Beziehung invertiert und die Abhängigkeiten werden ihm zur Verfügung gestellt.

Daher legen Ihre Klassen ihre Abhängigkeiten natürlich über Konstruktorargumente oder Eigenschaften offen. Wenn Sie diese Struktur verachten, bedeutet das, dass Sie das Muster nicht wirklich verstanden haben.

3voto

krosenvold Punkte 73093

Hier gibt es zwei unterschiedliche Fälle:

Im Produktionscode werden Sie niemals schreiben.

new BusinessProducts(dataContextImplementation)

weil Dependency Injection normalerweise die gesamte Objekthierarchie für Sie erstellt. Dies ist die "virale" Natur von Dependency-Injection-Mustern, sie neigen dazu, die volle Kontrolle über die Erstellung Ihrer Dienste zu übernehmen.

In Unit-Test-Code werden Sie diese normalerweise selbst erstellen, aber sehr oft werden Sie ein Mock-Objekt oder eine Stub-Implementierung von dataContextImplementation bereitstellen. Normalerweise werden Sie also ein Objekt injizieren, das nicht viele weitere Abhängigkeiten hat.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X