2009-02-19 14 views
7

ważne; Jestem naprawdę szukam odpowiedzi tutaj. Proszę nie mówić, jak to zrobić z Windsor, Spring, Unity lub dowolnym z the others.Konfigurowanie profili za pomocą szablonu StructureMap

Gram z StructureMap dla IoC - i zasadniczo moim celem jest posiadanie "domyślnego" profilu, który definiuje podstawowe typy i wiele nazwanych profili, które go zastępują/rozszerzają. I myśleć, że profile mogą to zrobić, ale po prostu nie mogę go uruchomić za pomocą xml lub API kodu. W szczególności, gdy próbuję załadować kontener dla profilu:

container = new Container(); 
container.SetDefaultsToProfile(profile); 

Potem dostajesz „Zamówiony Profile {nazwa} nie można znaleźć”, pomimo faktu, że wyraźnie o nazwie CreateProfile w initialize (o tej nazwie).

Czy szczerzę złe drzewo?

(również wysłane do user-group)


Co ja idealnie chcę, to aby móc określić standardowe (/ default) typów, a następnie przez szereg różnych nazwach konfiguracjach, override niektóre ustawienia - tj gdybym miał

  • globalne: IFoo =>Foo, IBar =>Bar
  • configA: (bez zmian)
  • configB: IFoo =>SpecialFoo

wierzę to może mapować do 2 pojemników, ładowane za pomocą nazwanych profili. Celem jest, że jeśli pytam albo pojemnik na IBar, otrzymuję Bar - ale configA zwraca Foo (dla IFoo), gdzie-jak configB zwraca SpecialFoo.

Czy ktoś może mi dać pojęcie, jak mogę to skonfigurować? Kod xml lub jest w porządku ... Po prostu chcę, żeby działał. Potrzebuję tylko mapowania typu z interfejsem API (nie ma specjalnych ustawień konfiguracji/właściwości).

Odpowiedz

9

Sztuką jest upewnienie się, że każdy pojedynczy profil jest co najmniej zdefiniowaną w nim regułą. Jeśli nie określisz reguły (configA), nie utworzy ona/nie zobaczy profilu.

Biorąc pod uwagę te zajęcia:

public interface IFoo { string SayHello(); } 
public class Foo : IFoo { public string SayHello() { return "Hello"; } } 
public class SpecialFoo : IFoo { public string SayHello() { return "Hello Special"; } } 

public interface IBar { } 
public class Bar : IBar { } 

public interface IDummy { } 
public class Dummy : IDummy{ } 

Można zdefiniować do rejestru:

public class MyRegistry : Registry 
{ 
    protected override void configure() 
    { 
     ForRequestedType<IBar>().TheDefault.Is.OfConcreteType<Bar>(); 
     ForRequestedType<IFoo>().TheDefault.Is.OfConcreteType<Foo>(); 
     CreateProfileNotEmpty("configA"); 
     CreateProfileNotEmpty("configB") 
      .For<IFoo>().UseConcreteType<SpecialFoo>(); 
    } 
    StructureMap.Configuration.DSL.Expressions.ProfileExpression CreateProfileNotEmpty(string profile) 
    { 
     return CreateProfile(profile) 
      .For<IDummy>().UseConcreteType<Dummy>(); 
    } 
} 

i będzie działać z tych testów:

[TestMethod] 
public void TestMethod1() 
{ 
    var container = new Container(new MyRegistry()); 
    Assert.IsNotNull(container.GetInstance<IBar>()); 
    Assert.AreEqual("Hello", container.GetInstance<IFoo>().SayHello()); 

    container.SetDefaultsToProfile("configB"); 
    Assert.IsNotNull(container.GetInstance<IBar>()); 
    Assert.AreEqual("Hello Special", container.GetInstance<IFoo>().SayHello()); 

    container.SetDefaultsToProfile("configA"); 
    Assert.IsNotNull(container.GetInstance<IBar>()); 
    Assert.AreEqual("Hello", container.GetInstance<IFoo>().SayHello()); 
} 

jeśli zastąpić CreateProfileNotEmpty z prostego CreateProfile , zawiedzie w wierszu, który ustawia wartość domyślną na configA.

+1

Interesujące. Spróbuję tego jutro. Traktuj to jako +1 (i być może "wygraną") - w tej chwili nie mam głosów ;-p –

Powiązane problemy