2009-08-17 11 views
2

J'ai fait un peu de googling et de recherche ici sur SO, mais n'a pas pu trouver une question ou une réponse similaire.Comment configurer des instances nommées à l'aide de profils StructureMap?

Dans la configuration de SM typique, vous pouvez ajouter plusieurs instances nommées pour un seul PluginType:

ForRequestedType<IFoo>() 
    .AddInstances(x => { 
     x.OfConcreteType<FooA>().WithName("FooA"); 
     x.OfConcreteType<FooB>().WithName("FooB"); 
    }); 

il n'y a pas de problème. Le problème est que je ne peux pas faire la même chose lors de la création d'un profil. La plupart des exemples expliquant comment utiliser les profils utilisent la méthode For<>() du passé ProfileExpression:

CreateProfile("Default", p => { 
    p.For<IFoo>().UseConcreteType<FooC>(); 
    }); 

Je ne peux pas sembler trouver un moyen d'ajouter plusieurs instances nommées pour la même PluginType que vous pouvez le faire ci-dessus avec une configuration régulière. La seule autre méthode disponible par ProfileExpression est Type<>(), mais je ne suis pas sûr si elle peut être utilisée à cette fin.

Edit: Je essayé d'utiliser Type<>() au lieu de For<>() et il semble me prendre dans la bonne direction, mais je suis tombé sur un autre problème. Pour mieux expliquer c'est ici un meilleur exemple de ce que je suis en train de faire (ce que j'affecté au groupe d'utilisateurs de StructureMap, pas encore de réponse):

ObjectFactory.Initialize(x => { 
    x.CreateProfile("Nissan", p => 
    { 
     p.Type<ICar>().Is.OfConcreteType<NewNissanCar>().WithName("New"); 
      p.Type<ICar>().Is.OfConcreteType<OldNissanCar>().WithName("Old"); 
    }); 

    x.CreateProfile("Honda", p => 
    { 
     p.Type<ICar>().Is.OfConcreteType<NewHondaCar>().WithName("New"); 
     p.Type<ICar>().Is.OfConcreteType<OldHondaCar>().WithName("Old"); 
    }); 

}); 

ObjectFactory.Profile = "Nissan"; 

ICar newCar = ObjectFactory.GetNamedInstance<ICar>("New"); // -> returns NewHondaCar 
ICar car = ObjectFactory.GetInstance<ICar>(); // -> returns OldNissanCar 

Donc, même si je mets le profil " Nissan ", GetNamedInstance<>("New") a renvoyé une instance du profil incorrect - il aurait dû renvoyer NewNissanCar au lieu de NewHondaCar.

Fait intéressant, GetInstance<>() utilise le bon profil, mais parce que je ne peux pas passer un nom d'instance, il retourne un type concret arbitraire de ce profil qui implémente ICar (je suppose qu'il retourne juste le dernier type de béton ajouté pour cette interface) .

Répondre

0

Je ne suis pas sûr à 100% sur la syntaxe, mais je crois que cela est correct:

container = new Container(x => { 

    x.ForRequestedType<IFoo>() 
     .AddInstances(y => 
     { 
      y.OfConcreteType<FooA>().WithName("FooA"); 
      y.OfConcreteType<FooB>().WithName("FooB"); 
     }); 

    x.CreateProfile("Default") 
     .For<IFoo>().UseNamedInstance("FooA"); 

}); 
+0

Cela fonctionnerait si je voulais réutiliser une instance nommée existante. Malheureusement, j'aimerais enregistrer un nouveau type de béton et lui donner un nom. Après avoir regardé l'exemple que j'ai donné dans la question, je pense que je n'aurais pas dû utiliser à nouveau FooA dans le profil. Je vais essayer de le réparer pour clarifier mon intention. – khaledh

0

Il ne ressemble pas à des égards StructureMap les instances nommées au niveau du profil. J'ai juste essayé l'exemple de la voiture avec SM 2.6.3 et obtenu les mêmes résultats. Vous pouvez également le voir dans la sortie de ObjectFactory.WhatDoIHave():

ICar (ConsoleApplication1.ICar)      
Scoped as: Transient 
     "New" Configured Instance of ConsoleApplication1.NewHondaCar, ConsoleApplication1 
     "Old" Configured Instance of ConsoleApplication1.OldHondaCar, ConsoleApplication1 

Il semble que les profils peuvent être mis en œuvre en interne en utilisant le nom aussi bien, ce qui expliquerait pourquoi il est pas pris en charge. Lorsque je me suis inscrit une instance non nommé pour chaque profil, je vois cela dans la sortie:

ICar (ConsoleApplication1.ICar)      
Scoped as: Transient 
     "Default Instance for Profile Nissan" Configured Instance of ConsoleApplication1.NewNissanCar, ConsoleApplication1 
     "Default Instance for Profile Honda" Configured Instance of ConsoleApplication1.NewHondaCar, ConsoleApplication1 

Remarquez comment le nom du profil est en fait une partie du nom de la clé d'instance. Je n'ai pas parcouru le code, mais c'est ce qui semble se produire.