StructureMap registriert generische Typen gegen alle möglichen konkreten Implementierungen

8

Ich habe folgendes:

%Vor%

Ich möchte mit dem Scannen den ICommandHandler & lt; & gt; damit ich die folgenden Typen im Container bekomme:

  • ICommandHandler<AddUser> mit Betontyp AddUserHandler
  • ICommandHandler<AddUser> mit Betontyp AuditTrailHandler

Ich habe das mit einer Implementierung von IRegistrationConvention versucht und irgendwann hatte ich es funktioniert, aber ich kann einfach nicht verstehen, wie ich es gemacht habe.

Das Ziel besteht darin, mehrere Handler für eine bestimmte ICommand-Implementierung wie folgt auszuführen:

%Vor%

Ich möchte, dass AuditTrailHandler<ICommand> für alle konkreten Implementierungen von ICommand ausgeführt wird, daher müssen sie für alle ICommand-Typen registriert werden.

Das zweite Ziel wäre, wenn ich eine Sammlung von ICommandHandlers<ICommand> in meinen CommandDispatcher anstelle des Containers injizieren könnte, aber ich denke, das ist mit der Struktur, die ich jetzt habe, unmöglich. Beweisen Sie mich falsch, wenn Sie irgendwelche Ideen haben.

BEARBEITEN - gelöst

Ich habe eine nicht generische Schnittstelle hinzugefügt, die meine generische Schnittstelle implementiert, und dann habe ich auch eine Zusammenfassung CommandHandler<T> hinzugefügt, so dass ich die Methoden CanHandle oder Execute (object) nicht in allen Handlern implementieren muss.

Dies ist die Arbeitsstruktur:

%Vor%

Und da dies ursprünglich eine StructureMap-Frage war, hier der Scan, um das hinzuzufügen:

%Vor%

Dadurch kann ich ein IEnumerable in meinen CommandDispatcher einfügen und so ausführen:

%Vor%

Dadurch kann ich CommandHandler ausführen, die AddUser unterstützen (wie den AddUserHandler), aber ich kann auch einen Handler ausführen, der ICommand unterstützt (wie der AuditTrailHandler).

Das ist süß!

    
Mikael Östberg 19.01.2011, 09:07
quelle

1 Antwort

4

Damit alle Befehlshandler in den Befehlsdispatcher injiziert werden, erstellen Sie eine neue, nicht generische ICommandHandler -Schnittstelle, von der ICommandHandler<T> abgeleitet wird. Es hat eine Execute-Methode, die ein Objekt übernimmt. Der Nachteil ist, dass jeder Ihrer Befehls-Handler diese Methode implementieren muss, um die typisierte Überladung aufzurufen:

%Vor%

Dies ermöglicht Ihrem Befehls-Dispatcher eine Konstruktorabhängigkeit von IEnumerable<ICommandHandler> , die von StructureMap automatisch ausgefüllt wird.

In SendCommand haben Sie zwei Möglichkeiten, um die passenden Handler zu erhalten. Ein einfacher Filter basierend auf dem Typ:

%Vor%

oder fügen Sie der Schnittstelle CanHandle(object command) eine ICommandHandler hinzu:

%Vor%

Der zweite Ansatz erfordert mehr Code, bietet Ihnen jedoch ein wenig mehr Flexibilität, da Sie den Handler an mehr als nur den Typ anhängen können. Dies kann die Lösung Ihres ersten Problems erleichtern, indem Ihr AuditTrailHandler immer true von CanHandle zurückgibt.

    
Joshua Flanagan 19.01.2011, 14:08
quelle

Tags und Links