2009-09-17 8 views
12

Mam interfejs podobny do tegoStructureMap, konstruktor, który pobiera listę wtyczek

public interface IWriter 
{ 
    ... 
} 

i klasę

public class WriterMerger 
{ 
    public WriterMerger(IEnumerable<IWriter> writers) 
    ... 
} 

chcę StructureMap wypełnić argument konstruktora na WriterMerger wszystkich zarejestrowanych IWriter-tych . Zarejestrowałem różnych pisarzy z

StructureMap.ObjectFactory.Initialize(x => 
{ 
    x.ForRequestedType<IWriter>().AddConcreteType<MemoryWriter>(); 
    x.ForRequestedType<IWriter>().AddConcreteType<FlatFileWriter>(); 
    x.ForRequestedType<IWriter>().AddConcreteType<DbWriter>(); 
} 

jednak dzwonisz

ObjectFactory.CreateInstance<WriterMerger>(); 

Zwraca wyjątek „Brak domyślnego wystąpienia zdefiniowanego dla PluginFamily System.Collections.Generic.IEnumerable`1 [[IWriter ..]] " (edytowano nazwę klasy)

Każda sztuczka do automatycznego wykonywania tej czynności? czy będę musiał wykonać niestandardową metodę fabryczną?

Odpowiedz

10

Gdy chcesz wszystkie konkretne przypadki typu mają być wstrzykiwane, należy zadeklarować parametr w postaci tablicy. Można rozwiązać problem zmieniając konstruktora:

public WriterMerger(IWriter[] writers) 

mieć świadomość, że narzędzia oczyszczania kod jak ReSharper mogą uwypuklić tablicę w swoim konstruktorze i proponuję zastąpić go IEnumerable, jeśli to wszystko, co jest wymagane przez WriterMerger. Jednak narzędzia te nie są świadome wymogu StructureMap dotyczącego korzystania z tablicy, więc należy ją zignorować.

Możesz być także zainteresowany wiedząc, że możesz automatycznie zarejestrować wszystkich swoich IWriterów zamiast ich jawnie wymieniać. Wystarczy zmienić konfigurację kontenera do:

StructureMap.ObjectFactory.Initialize(x => 
{ 
    x.Scan(scan => 
    { 
     scan.TheCallingAssembly(); 
     scan.AddAllTypesOf<IWriter>(); 
    }); 
}); 

Istnieje wiele różnych możliwości skanowania, które pozwalają skanować różne zespoły, wyłączenia niektórych rodzajów itp

1

Myślę, że to, co mówisz, to że musisz zdefiniować jeden z tych IWriterów jako domyślny. Wyobraź sobie inna klasa miała następujący contructor:

public class Test{ 
    public Test(IWriter writer){} 
} 

Bez domyślnie IWriter to nie wiem, który pisarz przypisać. Więc prawdopodobnie musisz powiedzieć, która z nich jest domyślna, nawet jeśli nigdy jej nie używasz. Zobacz ten post:

What's the difference between AddConcreteType and TheDefaultIsConcreteType in StructureMap?

2

I duplikowane swój problem i wierzę, że Twój Kod zadziała, jeśli zmienisz swoją klasę zużywającą IWriter, aby miała ctor, który pobiera tablicę IWriter.

public class WriterMerger { public WriterMerger(IWriter[] writers) } 

Josh jest na dobrej drodze, by polecić lepszy sposób rejestrowania wszystkich typów IWriter z StructureMap. Skanery FTW.

+0

Dzięki, że rozwiązał mój problem – AndreasN

18

Właściwie można to zrobić bez zmiany konstruktora

zmienić konfigurację kontenera do:

StructureMap.ObjectFactory.Initialize(x => 
{ 
    x.Scan(scan => 
    { 
     scan.TheCallingAssembly(); 
     scan.AddAllTypesOf<IWriter>(); 
    }); 
    x.ForRequestedType<IEnumerable<IWriter>>() 
     .TheDefault.Is.ConstructedBy(x => ObjectFactory.GetAllInstances<IWriter>()); 
}); 
+0

Chociaż wymaga to nieco więcej specyfikację, takie podejście jest mniej sprzężony Wymaganie StructureMap, aby określić kolekcję jako tablicę, a zatem otrzymuje ode mnie +1. –

+0

Dla osób używających SM3 wygląda na to, że 'ForRequestedType <>' został usunięty. –

+0

Nie używałem SM od jakiegoś czasu, ale wierzę, że ForRequestedType <> jest teraz tylko For <> –

Powiązane problemy