2010-11-21 5 views
3

Ich möchte IOC in meiner Anwendung implementieren, aber ich bin verwirrt, in meiner Anwendung habe ich mehrere konkrete Klassen, die eine Schnittstelle implementieren. Betrachten Sie dieses Szenario: -Verwenden von IOC-Container für mehrere Betontypen

Ich habe eine Inteface ICommand und folgende konkrete Typen, die diese Schnittstelle implementieren: -

  • AddAddress
  • Neuer Kontakt
  • RemoveAddress
  • RemoveContact

Grundsätzlich Benutzer führt alle diese Aktion in der Benutzeroberfläche aus, und dann wird List an die Serviceebene übergeben, wo eac Der h-Befehl wird ausgeführt.

So in GUI-Schicht werde ich

ICommand command1 = new AddAddress(); 
ICommand command2 = new RemoveContact(); 

In Befehl Krippe

List<ICommand> listOfCommands = List<ICommand>(); 
listOfCommands.Add(command1); 
listOfCommands.Add(command2); 

Dann schreiben schließlich listOfCommands zu Dienstschicht passieren.

Jetzt nach meinem Verständnis von IOC ist nur eine konkrete Klasse auf die Schnittstelle abgebildet. Und wir verwenden diese Syntax, um unseren konkreten Typ aus dem StructureMap-Container zu erhalten.

ICommand command = ObjectFactory.GetInstance<ICommand>(); 

Wie soll ich IOC in diesem Szenario implementieren?

Antwort

0

In den meisten IOC-Containern können Sie "benannte Instanzen" von Schnittstellen registrieren, so dass Sie mehrere Implementierungen von ICommand mit jeweils eigenem eindeutigen Namen registrieren können. In StructureMap, yourequestthem wie folgt aus:

ObjectFactory.GetNamedInstance<ICommand>("AddAddress"); 

Werfen Sie einen Blick auf this question, wie Sie Setup den Behälter in StructureMap zu sehen.

3

In diesem Szenario sind Sie besser dran, Ihre Befehle in Wertobjekte zu machen, das heißt nicht durch die IoC-Container erstellt:

class AddAddressCommand { 
    public AddAddressCommand(string address) { 
     Address = address; 
    } 
    public string Address { get; private set; } 
} 

Wenn Sie einen Befehl erstellen, die Sie wirklich eine spezifische Implementierung wünschen, und Sie wollen es genau parametrisieren, beide Bedenken, die gegen die Dienste des IoC-Containers arbeiten werden. Dies wird noch relevanter, wenn Sie sich irgendwann dazu entschließen, die Befehlsobjekte zu serialisieren.

Stattdessen macht die Service-Layer-Komponenten, die die Befehle in IoC bereitgestellten Komponenten ausführen :

In Ihrem Fall ist die Komponente, die die Liste der Befehle akzeptiert werden müssen, um den Befehl lösen geeignete Handler für jeden Befehl und senden Sie das Befehlsobjekt an ihn.

Es gibt einige Diskussionen darüber, wie man das mit Windsor macht: http://devlicious.com/blogs/krzysztof_kozmic/archive/2010/03/11/advanced-castle-windsor-generic-typed-factories-auto-release-and-more.aspx - die Community, die deinen IoC-Container deiner Wahl unterstützt, kann dir bei der Konfiguration helfen.

1

Wie von Mark erwähnt, wird StructureMap können Sie benannte Instanzen einer Schnittstelle einzurichten und zu rufen:

ObjectFactory.Initialize(x => 
{ 
    x.For<ISomeInterface>().Add<SomeImplementation>().Named("SomeName"); 
} 

Sie können immer noch eine Standardinstanz für diese spezielle Schnittstelle, natürlich hinzufügen:

ObjectFactory.Initialize(x => 
{ 
    x.For<ISomeInterface>().Add<DefaultImplementation>();  
    x.For<ISomeInterface>().Add<SomeImplementation>().Named("SomeName"); 
} 

Wenn Sie ObjectFactory.GetInstance<ISomeInterface>(); aufrufen, wird die Standardinstanz (die mit Use anstelle von Add initialisiert wird) zurückgegeben.

ObjectFactory.Initialize(x => 
{ 
    // names are arbitrary 
    x.For<ICommand>().Add<AddAddress>().Named("AddAddress"); 
    x.For<ICommand>().Add<RemoveContact>().Named("RemoveContact"); 
} 

Diese Wie von Mark genannt würde:

Also in Ihrem Fall würde die Einrichtung etwas aussehen

ObjectFactory.GetNamedInstance<ICommand>("AddAddress"); 
ObjectFactory.GetNamedInstance<ICommand>("RemoveContact"); 

Hoffnung, das hilft.

Verwandte Themen