2009-02-19 3 views
7

wichtig; Ich bin wirklich auf der Suche nach einer StructureMap Antwort hier. Bitte sagen Sie nicht, wie Sie es mit Windsor, Spring, Unity oder irgendeinem von the others machen.Konfigurieren von Profilen mit StructureMap

Ich spiele mit StructureMap für IoC - und im Grunde ist mein Ziel, ein "Standard" -Profil zu haben, das die Kerntypen definiert, und eine Anzahl von benannten Profilen, die dies überschreiben/erweitern. I denke,, dass Profile dies tun können, aber ich kann es einfach nicht über die XML-API oder die Code-APIs zu arbeiten. Insbesondere versuchen, wenn ich für ein Profil, einen Behälter zu laden:

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

Dann bekomme ich „Profil Gewünscht {name} kann nicht gefunden werden“, trotz der Tatsache, dass ich deutlich CreateProfile in der initialize genannt (mit diesem Namen).

Banne ich den falschen Baum an?

(auch user-group veröffentlicht)


Was ich im Idealfall will in der Lage sein, die Standard (/ default) Typen zu definieren und dann für eine Reihe von verschiedenen Namen Konfigurationen, Überschreibung einige der Einstellungen - also wenn ich

  • global hatte: IFoo =>Foo, IBar =>Bar
  • CONFIGA: (keine Änderungen)
  • configB: IFoo =>SpecialFoo

Ich glaube, dies zu 2 Container Karte könnte, mit dem Namen Profile geladen. Der Zweck ist, dass, wenn ich so oder Behälter für eine IBar fragen, erhalte ich eine Bar - aber CONFIGA gibt einen Foo (für IFoo), wo-wie configB gibt ein SpecialFoo.

Kann mir jemand einen Hinweis geben, wie ich das konfigurieren kann? Entweder xml oder Code ist in Ordnung ... Ich will nur, dass es funktioniert. Alles, was ich brauche, ist eine Schnittstelle zu konkreten Zuordnungen (keine speziellen Einstellungen für Konfiguration/Eigenschaften).

Antwort

9

Der Trick besteht darin, sicherzustellen, dass jedes einzelne Profil mindestens eine darin definierte Regel enthält. Wenn Sie keine Regel (configA) angeben, wird das Profil nicht erstellt/angezeigt.

Unter diesen Klassen:

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{ } 

Sie können diesen Registrierungs definieren:

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>(); 
    } 
} 

Und es wird mit diesen Tests arbeiten:

[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()); 
} 

wenn Sie CreateProfileNotEmpty mit einfachen Create ersetzen Es wird in der Zeile fehlschlagen, die den Standardwert für configA festlegt.

+1

Interessant. Ich werde das morgen versuchen. Betrachte es als +1 (und möglicherweise als "den Sieg") - ich bin gerade nicht in der Wahl –