2010-11-22 21 views
1

classes concrètes et Compte tenu des interfaces ayant des noms qui ne correspondent pasStructureMap configurer des classes de béton dont les noms ne correspondent pas à l'interface

Harvester_JohnDeere_Parsley : AbstractMachine, IParsleyHarvester 
Harvester_NewHolland_Sage : AbstractMachine, ISageHarvester 
Harvester_Kubota_Rosemary : AbstractMachine, IRosemaryHarvester 

où les interfaces ont un parent commun

IParsleyHarvester : ISpiceHarvester 
ISageHarvester : ISpiceHarvester 
IRosemaryHarvester : ISpiceHarvester 

comment peut StructureMap être configuré pour que les instances de I ... Harvester puissent être injectées dans le constructeur

public ParsleyField(IParsleyHarvester parsleyHarvester) 

sans avoir à configurer chaque paire individuellement dans le Registre? par exemple.

For<ISageHarvester>().Use<Harvester_NewHolland_Sage>(); 

J'ai essayé la numérisation

Scan(x => 
{ 
    x.AssemblyContainingType<Harvester_Kubota_Rosemary>(); 
    x.AddAllTypesOf<ISpiceHarvester>(); 

mais je ... interfaces abatteuse ne suis pas sur la carte.

Merci!

modifier:

fonctionnent deux réponses. @ jeroenh a l'avantage que des clauses de garde peuvent être ajoutées pour exclure des classes (pour une raison quelconque). Voici un exemple basé sur la réponse de @ Mac à this question.

public class HarvesterConvention : StructureMap.Graph.IRegistrationConvention 
{ 
    public void Process(Type type, Registry registry) 
    { 
     // only interested in non abstract concrete types 
     if (type.IsAbstract || !type.IsClass) 
      return; 

     // Get interface 
     var interfaceType = type.GetInterface(
      "I" + type.Name.Split('_').Last() + "Harvester"); 

     if (interfaceType == null) 
      throw new ArgumentNullException(
       "type", 
       type.Name+" should implement "+interfaceType); 

     // register (can use AddType overload method to create named types 
     registry.AddType(interfaceType, type); 
    } 
} 
utilisation

:

Scan(x => 
{ 
    x.AssemblyContainingType<Harvester_Kubota_Rosemary>(); 
    x.Convention<HarvesterConvention>(); 
    x.AddAllTypesOf<ISpiceHarvester>(); 

Répondre

1

StructureMap ne connaît pas votre convention. Vous devez le dire en ajoutant une convention d'enregistrement personnalisée. Mettre en œuvre l'interface IRegistrationConvention, et ajoutez la convention au scanner de montage:

Scan(x => 
    { 
    x.Convention<MyConvention>(); 
    } 
1

J'adapté une solution de @ réponse de Kirschstein à this question.

Scan(x => 
{ 
    x.AssemblyContainingType<Harvester_Kubota_Rosemary>(); 
    x.AddAllTypesOf<ISpiceHarvester>() 
    .NameBy(type => "I" + type.Name.Split('_').Last() + "Harvester"); 

Définit la manière de convertir le nom de la classe concrète en son nom d'interface à des fins de recherche.