Gibt es einen Grund, nicht meine IoC als allgemeine Einstellungen Repository zu verwenden?

StackOverflow https://stackoverflow.com/questions/115039

  •  02-07-2019
  •  | 
  •  

Frage

Nehmen wir an, dass die Application Klasse ist eine allgemeine Sammlung von Einstellungen, die für meine Anwendung wie TimeoutPeriod, DefaultUnitOfMeasure, HistoryWindowSize usw. anwenden ... Und lassen Sie uns sagen, MyClass Verwendung eines dieser Einstellungen macht - DefaultUnitOfMeasure.

Meine Lesart der bestimmungsgemäßen Verwendung der Inversion of Control Container - und bitte korrigieren Sie mich, wenn ich das falsch bin - ist, dass Sie die Abhängigkeiten einer Klasse im Konstruktor definieren:

public class MyClass {
  public MyClass(IDataSource ds, UnitOfMeasure default_uom) {...}
} 

und rufen Sie dann Ihre Klasse mit etwas instanziiert wie

var mc = IoC.Container.Resolve<MyClass>();

Wo IDataSource hat eine konkrete Umsetzung und default_uom wurde verdrahtet zu instanziiert aus dem ApplicationSettings.DefaultUnitOfMeasure Eigenschaft zugeordnet. Ich habe jedoch zu fragen, ob all diese Reifen sind wirklich notwendig zu springen durch. Was wie ein Problem bin ich selbst bis zur Einstellung soll ich tun

public class MyClass {
  public MyClass(IDataSource ds) {
    UnitOfMeasure duom = IoC.Container.Resolve<UnitOfMeasure>("default_uom");
  }
} 

Ja, am Ende viele meiner Klassen nach oben mit einer Abhängigkeit von IoC.Container , aber das ist eine Abhängigkeit, die die meisten meiner Klassen haben sowieso. Es scheint, wie ich vielleicht voll davon Gebrauch machen sollte, solange die Klassen gekoppelt sind. Bitte Agile Gurus, sagen Sie mir, wo ich falsch bin.

War es hilfreich?

Lösung

  

IoC.Container.Resolve ( "default_uom");

Ich sehe dies als klassische anti-Muster, in dem Sie den IoC-Container als Dienst locater verwenden - die wichtigsten Fragen, die sich ergeben, sind:

  • Ihre Anwendung nicht mehr ausfällt schnellen, wenn Ihr Behälter falsch konfiguriert ist (nur über sie zum ersten Mal in Code, die bestimmten Dienst zu lösen versucht, wissen werden, die bis auf einen bestimmten Satz von Logik / Umständen auftreten könnte, nicht) .
  • Harder Test - nicht unmöglich, natürlich, aber Sie haben entweder eine echte (und halb konfiguriert) Instanz des windsor Container für Ihre Tests zu erstellen oder die Singleton mit einem Mock von IWindsorContainer zu injizieren - das fügt eine Menge Reibungs zum Testen, im Vergleich zu nur in der Lage zu sein, die Mock / Stub-Dienste direkt in der Klasse im Test über Konstrukteuren / Eigenschaften.
  • passieren
  • Härtere diese Art von Anwendung zu halten (Konfiguration ist in einem Ort nicht zentralisiert)
  • Violates eine Reihe von anderen Software-Entwicklungsprinzipien (DRY, SOC usw.)

Der über einen Teil Ihrer ursprünglichen Anweisung ist die Implikation, dass die meisten Ihrer Klassen eine Abhängigkeit von Ihrem IoC Singletons haben - wenn sie bekommen alle Dienste injiziert in über Konstrukteuren / Abhängigkeiten dann IoC einige enge Kopplung mit sein sollte die Ausnahme von der Regel - im allgemeinen die einzige Zeit, die ich auf dem Behälter eine Abhängigkeit nehmen ist, wenn ich eine zirkuläre Abhängigkeit Probleme tue etwas versuchen, knifflige also zu vermeiden, oder wollen Komponenten zur Laufzeit aus irgendeinem Grund zu schaffen, und sogar ich kann dann oft vermeiden eine Abhängigkeit nehme mehr als Schnittstelle eines generischen IServiceProvider auf etwas, so dass mich in einer Heim-bake IoC oder Service locater Implementierung tauschen, wenn ich die Komponenten in einer Umgebung außerhalb des ursprünglichen Projektes wiederverwenden muß.

Andere Tipps

Ich habe in der Regel nicht viele Klassen je nach meiner IoC-Container. Ich versuche, in der Regel die IoC Sachen in einer Fassade Objekt zu wickeln, die ich in anderen Klassen zu injizieren, in der Regel die meisten meiner IoC Injektion nur wenn in den höheren Schichten meiner Anwendung durchgeführt wird.

Wenn Sie Dinge tun, Ihren Weg Sie nicht MyClass testen können eine IoC Konfiguration für Ihre Tests ohne zu schaffen. Dies wird Ihre Tests schwieriger aufrecht zu erhalten.

Ein weiteres Problem ist, dass Sie Poweruser Ihrer Software haben werden, die die Konfiguration der Bearbeitung Ihrer IoC Konfigurationsdateien ändern möchten. Das ist etwas, was ich wollen würde zu vermeiden. Sie könnten Ihre IoC Config in eine normale Konfigurationsdatei und die IOK speziellen Sachen aufgeteilt. Aber dann könnte man genauso gut die normale .NET-Konfigurationsfunktionalität verwenden, um die Konfiguration zu lesen.

  

Ja, enden viele meiner Klassen mit einer Abhängigkeit von IoC.Container, aber das ist eine Abhängigkeit, die sowieso die meisten meiner Klassen haben wird.

Ich denke, das der Kern des Problems ist. Wenn in der Tat die meisten Klassen an dem Behälter IoC gekoppelt sind, sich die Chancen sind Sie brauchen Ihr Design zu überdenken.

Im Allgemeinen Ihre Anwendung sollte nur auf die Container-Klasse beziehen sich direkt einmal während des Bootstrapping. Nachdem Sie diesen ersten Haken in den Behälter sollte der Rest des Objektgraphen vollständig vom Container verwaltet werden und alle diese Objekte sollten die Tatsache nicht bewusst sein, dass sie durch einen IoC-Container erstellt wurden.

Um einen Kommentar auf Ihrem spezifisches Beispiel:

public class MyClass {
    public MyClass(IDataSource ds) {
        UnitOfMeasure duom = IoC.Container.Resolve<UnitOfMeasure>("default_uom");
    }
}

Das macht es schwieriger, Ihre Klasse wiederverwenden. Genauer gesagt macht es schwieriger, Ihre Klassenmuster außerhalb der schmalen Nutzung instanziiert Sie sie sind zu beschränken. Einer der häufigsten Orte, an denen wird sich manifestieren, wenn Sie Ihre Klasse zu testen. Es ist viel einfacher, diese Klasse zu testen, ob die UnitOfMeasure können direkt an den Konstruktor übergeben werden.

Auch Ihre Wahl des Namens für die ME-Instanz ( „default_uom“) bedeutet, dass der Wert außer Kraft gesetzt werden könnte, abhängig von der Verwendung der Klasse. In diesem Fall würden Sie den Wert nicht in dem Konstruktor, so zu „hard-Code“ werden sollen.

das Konstruktor Einspritzmuster Mit nicht Ihrer Klasse auf dem IoC abhängig machen, genau das Gegenteil es gibt die Möglichkeit, Kunden die IoC oder nicht zu verwenden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top