Ich betrachte die Controller in meiner Website und die meisten ihrer Konstruktoren sehen so aus:
%Vor%Mit anderen Worten, es ist sehr haarig und macht das Refactoring schwierig. Einige Controller haben ungefähr 8 Abhängigkeiten.
Gibt es irgendeine Möglichkeit, diese Abhängigkeiten irgendwie in einen oder mehrere Buckets zu "gruppieren"?
Zum Beispiel ist ILoggingService
in jedem Controller erforderlich, IGeospatialService
wird von Controllern benötigt, die räumliche Objekte verwenden, und IServiceOne
und IServiceTwo
sind nur in bestimmten Fällen erforderlich.
Ich würde gerne so etwas sehen:
%Vor% Ich denke, es wäre gut, einige OO-Techniken einzuführen, wie zum Beispiel eine "Basis" -Abhängigkeitsklasse, die ein ILoggingService
in ihrem geschützten ctor benötigt. Dann haben Sie möglicherweise eine andere Kindabhängigkeit, die erbt, usw.
Hat jemand das schon mal gemacht? Ist das etwas, was StructureMap für mich tun kann, oder rolle ich einfach meinen eigenen Basiscode?
Protokollierung
Wenn eine Abhängigkeit in jedem einzelnen Controller erforderlich ist, ist dies ein ziemlich sicherer Hinweis darauf, dass es sich nicht um eine 'normale' Abhängigkeit handelt, sondern eher um eine Querschnittsfunktion . Logging ist das archetypische Beispiel für ein Cross-cutting Concern, also sollte ILoggingService
wie jedes andere Cross-cutting Concern behandelt werden.
In SOLID OO wäre der richtige Weg, ein Cross-cutting-Problem anzusprechen, zu beschäftigen ein Dekorateur (welches kann in Richtung AOP verallgemeinert werden ). Die ASP.NET MVC Controller-Aktionsmethoden sind jedoch nicht Teil einer Schnittstelle, daher ist dies eine weniger ideale Lösung.
Stattdessen stellt das MVC-Framework Aktionsfilter zu Überwachungszwecken bereit . Wenn Sie einen lose gekoppelten Filter implementieren möchten, tun Sie sich selbst einen Gefallen und implementieren Sie ihn anstelle eines Attributs als globalen Filter.
Andere Abhängigkeiten
Für andere Abhängigkeiten ist es sinnvoll refactor sie zu Facade Services . Dies beinhaltet das Identifizieren von natürlichen Clustern verwandter Dienste, so dass genau dies für jede Codebasis spezifisch ist.
Ich weiß, dass ich die Antwort von @Mark Seeman vor einiger Zeit akzeptiert habe, aber ich habe jetzt endlich Zeit, dies jetzt umzusetzen, also dachte ich, ich würde das teilen, was ich tat, zum Nutzen anderer.
Grundsätzlich habe ich Wrapper-Interfaces für die "Gruppen" von Abhängigkeiten in meiner Anwendung erstellt.
Beispiel:
%Vor%Und die Implementierung:
%Vor%Ziemlich einfach wirklich.
Dann habe ich meine Controller aktualisiert.
Beispiel ctor vorher:
%Vor%Nachher:
%Vor%Nichts wirklich Besonderes, nur eine Reihe von Wrappern. Unter der Haube nutzen die Controller immer noch die gleichen Abhängigkeiten, aber die ctor-Signatur ist viel kleiner, lesbarer und erleichtert das Testen von Einheiten.
Ich sehe ein paar Optionen:
Verwendung: Logger.Instance().Log(message);
Testen: Logger.Instance = () => new TestLogger();
Tags und Links asp.net-mvc c# dependency-injection dependency-management