Ein IoC-Container ist normalerweise nützlich, um Objekte mit Status zu injizieren. oder Klassen oder Schnittstellen, die mehr als eine Implementierung haben, selbst wenn die zweite Implementierung zu Testzwecken ein Mock ist. Wenn beides nicht wahr ist, gewinnen Sie nichts, indem Sie es injizieren.Das gebräuchlichste Idiom dieser Tage ist es, Ihre Klasse mit einer Schnittstelle zu konfrontieren, die sowohl die echte als auch die Scheinimplementierung implementieren können.
1) Statische Methoden auf Hilfsklassen - Nein, diese werden nicht oft von IoC injiziert. Normalerweise sind sie zustandslose Dienstprogramme. Um ein sehr einfaches Beispiel zu verwenden, benötigen Sie nicht zwei Versionen einer Hilfsmethode namens StringUtils.Reverse()
. Sie brauchen nur einen, und Sie können leicht Tests um ihn herum schreiben, weil er keinen Status oder Abhängigkeiten hat, so dass es absolut keinen Vorteil hat, sich darüber lustig zu machen. Beispiel Test:
string reversedString = StringUtils.Reverse("input");
Assert.AreEqual("tupni", reversedString)
Wenn das Dienstprogramm nicht wirklich staatenlos ist (zum Beispiel abhängig von HttpContext.Current), dann sollten Sie die Abhängigkeit explizit machen, indem sie die Injektion und nicht machte das Dienstprogramm statisch.
2) Singletons: Oft ja, Singletons werden injiziert. Aber eine gute Sache über IoC ist, dass Sie sich weniger Gedanken darüber machen, ob es nur etwas gibt oder nicht. Durch die Verwendung von IoC gewinnen Sie Flexibilität bei der Instanziierung. Die Entscheidung, einen bestimmten Typ jedes Mal als Singleton oder als neue Instanz zu definieren, wird Teil der Konfiguration des IoC-Containers, und nichts anderes im Code muss geändert werden.
So Singleton-Haube stoppt, ein separates Anliegen, das in die Klasse (und Klassen mit mehreren Bedenken, wenn sie nicht müssen, ist schlecht) codiert werden, und es wird das Anliegen des IoC-Container. Du schreibst die Klasse "as a Singleton" nicht mit etwas Speziellerem wie einem privaten Konstruktor und einer public static GetInstance()
Methode, sondern kodierst sie nur für das Hauptproblem, während die Konfig des IoC Containers angibt, ob es ein Singleton ist oder nicht oder irgendwo dazwischen, wie eine Instanz pro Thread.
3) Statische Klassen - sind das natürliche Zuhause für statische Methoden. Ziehen Sie gegebenenfalls die Erweiterungsmethoden für statische Methoden in Betracht. Sie können diese Klassen nicht injizieren, da Sie sie nicht erstellen können. Die Verwendung von statischen Klassen sorgt für prozeduralen, nicht objektorientierten Code. Dies ist keine schlechte Sache für kleine Hilfsmethoden, aber wenn der Großteil des Codes so ist, dann verwenden Sie nicht die leistungsstarken OO-Funktionen der .Net-Plattform.
danke Bryan - Bedeutet das, dass es immer mehr Overhead von der IOC Konstruktion Dinge (z. B. Logger) jedes Mal sein könnte? Auch für die Klassen vom Typ utils wundere ich mich, dass das Refactoring schwieriger wird, wenn Sie Ihre Hilfsfunktionen in Ihren Hilfsklassen umgestalten? (Ich benutze ReSharper selbst) - danke – Greg
Die meisten IoC-Container erlauben eine Art von Scoping. Damit meinen Sie, dass Ihr Objekt jedes Mal erstellt wird (Fabrik), einmal pro Kontext (Arbeitseinheit) oder einmal pro Anwendung (Singleton) erstellt wird. Dies bedeutet, dass Sie den Logger so registrieren können, dass er nur einmal erstellt wird. –
Schließlich möchten Sie die Dienstprogrammklassen beseitigen. Jede Methode für jede dieser Klassen hat die gleichen Kopplungsprobleme wie die oben beschriebene Methode "HttpUtils.DoStuff". Aus diesem Grund möchten Sie nicht verlangen, dass * irgendein * Code direkt von 'statischen' Mitgliedern abhängt. Nimm stattdessen den Körper von 'HttpUtils.DoStuff', lege ihn hinter' IDoesStuff' und lösche die Methode vollständig aus 'HttpUtils'. Nun kann jede Klasse, die die statische Methode aufgerufen haben könnte, stattdessen "IDoesStuff" in ihrem Konstruktor akzeptieren. Viola: keine Notwendigkeit mehr für die Nutzungsklasse! –