2009-02-19 6 views
7

important; Je suis vraiment à la recherche d'un StructureMap répondre ici. S'il vous plaît ne dites pas comment le faire avec Windsor, Spring, Unity, ou l'un des the others. Je joue avec StructureMap pour IoC - et mon objectif est essentiellement d'avoir un profil "par défaut" qui définit les types de base, et un certain nombre de profils nommés qui surchargent/étendent cela. Je pense que les profils peuvent le faire, mais je ne peux tout simplement pas le faire fonctionner à travers le xml ou les API de code. En particulier, si je tente de charger un conteneur pour un profil:Configuration de profils avec StructureMap

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

Puis-je obtenir « Profil demandé {nom} ne peut pas être trouvé », en dépit du fait que j'ai appelé clairement CreateProfile dans le initialize (avec ce nom).

Est-ce que j'aboie le mauvais arbre?

(également affiché à user-group)


Ce que je veux idéalement est d'être en mesure de définir la norme(/ par défaut) types , puis pour une gamme de configurations différentes nommées, override certains paramètres - à savoir si je devais

  • global: IFoo =>Foo, IBar =>Bar
  • configA: (aucun changement)
  • configB: IFoo =>SpecialFoo

Je crois que cela pourrait la carte 2 conteneurs, chargé à l'aide des profils nommés. Le but étant que si je demande soit contenant un IBar, je reçois un Bar - mais configA retourne une Foo (pour IFoo), où, comme configB retourne un SpecialFoo. Est-ce que quelqu'un peut me donner une idée de comment je peux configurer cela? Le code xml ou est bien ... Je veux juste que ça marche. Tout ce dont j'ai besoin est l'interface-à- mappages de type concret (pas de paramètres de configuration/propriété spéciaux).

Répondre

9

L'astuce consiste à s'assurer que chaque profil est au moins une règle définie en elle. Si vous ne spécifiez pas de règle (configA), le profil ne sera pas créé/vu.

Compte tenu de ces classes:

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

Vous pouvez définir ce registre:

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

Et il va travailler avec ces tests:

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

si vous remplacez CreateProfileNotEmpty avec CreateProfile simples , il échouera sur la ligne qui définit la valeur par défaut à configA.

+1

Intéressant. Je vais essayer ça demain. Considérez-le comme un +1 (et peut-être «la victoire») - Je suis juste à court de votes pour le moment ;-p –