2012-04-05 16 views
0

Auf Kozmics Blog (vom 2009) empfiehlt er eine generische Fabrik, um Objekte aus dem Container abzurufen. Nun, das scheint mir ein Pseudo-Service-Locator zu sein. Also ich möchte hier die Meinung von Experten einholen.Castle Windsor Generic Typed Factory

public interface IGenericFactory 
    { 
     T Create<T>(); 
    } 

Kann ich damit Objekte aus dem Windsor Container holen? Gibt es Nachteile bei diesem Ansatz?

Update:

Eigentlich möchte ich es nur für ein paar Transienten zu bekommen, die ich will nicht für mehrere Fabriken erstellen. Mit einer Fabrik für alle diese Szenarien.

Antwort

1

habe ich eine schnelle Google-Suche und fand diesen Artikel, die Sie wahrscheinlich auf sich beziehen: http://kozmic.pl/2009/12/23/castle-typed-factory-facility-reborn/

Wenn das der Fall ist, dann Krzysztof Kozmic sagt es selbst:

[...] Mit buchstäblich keiner Anstrengung können Sie es verwenden, um einen generischen Service Locator zu bauen.

Ja, heutzutage Service Locator is considered to be an anti-pattern.

Allerdings handelt der Artikel über Ausnahmefälle. Der Autor setzt es ganz klar im ersten Absatz:

Faustregel, wenn IoC Container verwendet, ist - wenn Sie Ihren Container in Ihren Komponenten Referenzierung (irgendwo außerhalb des Bootstrapping-Code) Sie es tun falsch. Wie bei allen Regeln gibt es Ausnahmen, aber sie sind selten. Statt

+0

@ w0lf-Mit der generischen Fabrik Ansatz muss ich nicht auf den Container in meinem Code verweisen. Ich registriere es als getippte Fabrik und Boom. Injizieren Sie die Fabrik und erhalten Sie alles, was Sie wollen! (Eigentlich möchte ich es verwenden, um nur ein paar Transienten zu erhalten, für die ich nicht mehrere Fabriken erstellen möchte).Ich möchte sicherstellen, dass dies gut oder schlecht ist? – user1178376

+0

@ user1178376 Das Problem mit diesem Ansatz ist, dass es tatsächlich ein Abstract Service Locator ist, der die Abhängigkeiten einer Klasse leicht verbergen kann. Um dies und die damit verbundenen Wartungsprobleme zu vermeiden, versuchen Sie es mit einfachen Konstruktorinjektionen und spezialisierten Fabriken. – GolfWolf

+1

Beachten Sie auch den Kommentar von Nicholas Blumhardt. Er beschreibt es sehr deutlich: "Es könnte versuchen, buchstäblich alles zu schaffen - und das macht es schwieriger zu warten und zu testen." – Steven

1

, Folgendes beachten:

public interface IGenericFactory<out T> 
{ 
    T Create(); 
} 

Die Schnittstelle muss nur einmal erstellt werden, aber es muss für jeden Dienst injiziert werden Sie lösen müssen. Auf diese Weise ist es kein generischer Service-Locator (der ein Anti-Pattern ist, wie bereits von w0lf erwähnt).

Bonuspunkte:

Normale Dependency Injection erfordert, dass alle Dienste in Ihrem Abhängigkeitsgraphen aufgelöst werden kann. IGenericFactory<> wird automatisch über die getippte Fabrikeinrichtung aufgelöst. Das Argument des generischen Typs wird jedoch erst bei der Ausführung von Create() aufgelöst.

Wenn dies in einem Randfall tief in Ihrem Programm passiert, und Sie vergessen, den Dienst zu registrieren, können Sie den Fehler bis zur Produktion nicht erkennen.

Die Lösung besteht darin, einen benutzerdefinierten Resolver für IGenericFactory<> zu schreiben, der überprüft, ob das generische Argument einen Handler hat und nicht darauf wartet, dass Abhängigkeiten registriert werden. Informationen über benutzerdefinierte Resolver ist hier: http://docs.castleproject.org/Windsor.Resolvers.ash