2010-06-22 5 views

Antwort

4

Im Kern erstellt ein DI-Container Objekte basierend auf Zuordnungen zwischen Schnittstellen und Betontypen.

Dies ermöglicht Ihnen eine abstrakte Art aus dem Behälter zu verlangen:

IFoo f = container.Resolve<IFoo>(); 

Dies erfordert, dass Sie zuvor der Behälter konfiguriert von IFoo auf eine konkrete Klasse zuzuordnen, die IFoo (zB Foo implementiert).

Dies wäre an sich nicht besonders beeindruckend, aber DI Container mehr tun:

  • Sie verwenden Auto-Wiring was bedeutet, dass sie automatisch herausfinden, dass, wenn IFoo zu Foo Karten und IBar abbildet Bar, aber Foo hat eine Abhängigkeit von IBar, es erstellt eine Foo-Instanz mit einem Balken, wenn Sie IFoo anfordern.
  • Sie verwalten die Lebensdauer von Komponenten. Sie möchten jedes Mal eine neue Instanz von Foo, aber in anderen Fällen möchten Sie vielleicht die gleiche Instanz. Vielleicht möchten Sie sogar jedes Mal neue Instanzen von Foo, aber der injizierte Balken sollte dieselbe Instanz bleiben.

Sobald Sie anfangen, versuchen, manuell Zusammensetzung zu verwalten und Lebensdauer Sie die Dienste von einem DI Container zur Verfügung gestellt zu schätzen beginnen sollte :)

Viele DI Container können als die oben viel mehr tun, aber diejenigen, sind die Kerndienste. Die meisten Container bieten Optionen für configuring via either code or XML.

Wenn es um richtige Verwendung von Containern kommt, hat Krzysztof Kozmic gerade a good overview veröffentlicht.

2

Sie konfigurieren einen DI-Container, damit er Ihre Schnittstellen und Typen kennt - wie jede Schnittstelle einem Typ zugeordnet ist.

Wenn Sie Resolve darauf aufrufen, sieht es sich das Mapping an und gibt das gemappte Objekt zurück, das Sie angefordert haben.

Einige DI-Container verwenden Konventionen über die Konfiguration. Wenn Sie beispielsweise eine Schnittstelle ISomething definieren, wird nach einem konkreten Something-Typ gesucht, der instanziiert und zurückgegeben wird.

+0

Kurz & Süß & frei von giftigen Autoanalogien! – Shog9

4

Es ist nichts anderes als eine Phantasie Hash Tabelle von Objekten.

Während die oben eine massive Untertreibung ist, das Denken über sie der einfache Weg ist. Wenn Sie bei der Sammlung nach der gleichen Instanz einer Klasse fragen, entscheidet der DI-Container, ob Sie eine zwischengespeicherte Version oder eine neue Version erhalten sollen.

Ihre Verwendung macht es einfacher und sauberer, wenn es um die Verdrahtung von Abhängigkeiten geht. Stellen Sie sich vor, Sie haben die folgenden Pseudo-Klassen.

class House(Kitchen, Bedroom) 
    // Use kitchen and bedroom. 
end 

class Kitchen() 
    // Code... 
end 

class Bedroom() 
    // Code... 
end 

Bau eines Hauses ist ein Schmerz ohne DI-Container, würden Sie eine Instanz aus einem Schlafzimmer schaffen müssen, durch eine Instanz einer Küche gefolgt. Wenn diese Objekte auch Abhängigkeiten hätten, müssten Sie sie verkabeln. Im Gegenzug können Sie viele Codezeilen ausgeben, um nur Objekte zu verkabeln. Nur dann könnten Sie ein gültiges Haus erstellen. Mit einem DI/IOC-Container (Inversion of Control) sagen Sie, Sie wollen ein Hausobjekt, der DI-Container erstellt rekursiv alle Abhängigkeiten und gibt Ihnen ein Haus zurück.

ohne DI/IOC Container:

house = new House(new Kitchen(), new Bedroom()); 

Mit DI/IOC Container:

house = // some method of getting the house 

Am Ende des Tages machen sie Code einfach zu folgen, leichter zu schreiben und verschieben die Verantwortung der Verdrahtung von Objekten zusammen von dem Problem zur Hand.

+0

Es sollte angemerkt werden, dass DI gut ist, weil es Sie davon abhält, Ihre eigenen komplexen Konstruktoren und Ihren eigenen Code zu schreiben, um Dinge und eine Menge anderer Sachen wie diese zu konfigurieren. Ja, du brauchst es nicht, es ist schön, eine vorhandene Bibliothek nutzen zu können, um all das für dich zu erledigen. Es macht das Konfigurieren von Java-Anwendungen (C# ist nicht mein Fachgebiet) ein wenig wie das Arbeiten mit einer - schlechten, inkonsistenten, überkomplexen - Skriptsprache ... –