2010-09-02 12 views
1

J'ai un constructeur qui prennent deux interfaces, ils sont la même interface, mais elles doivent être différentes implémentations:Comment utiliser sturcturemap pour passer deux implémentations différentes d'une interface unique dans un constructeur?

public class Foo 
{ 
    public Foo(IBar publicData, IBar privateData) 
    { 
    } 
} 

Ce que je voudrais arriver est que StructureMap passerait dans une mise en œuvre concrète de IBar comme class PublicData et class PrivateData pour les différents arguments. Est-ce possible?

MISE À JOUR

En fait, pour vous assurer qu'il ya assez d'informations:

Les classes réelles que je travaille ressembler à ceci:

public abstract class EFRepository<T> : IRepository<T> 
{ 
    protected EFRepository(IUnitOfWork publicUnitOfWork, 
          IUnitOfWork privateUnitOfWork) 
    { 

    } 
} 

et une mise en œuvre EFRepository pourrait ressembler à ceci:

public partial class ClaimRepository: EFRepository<Claim>, IClaimRepository 
{ 
    public ClaimRepository(IUnitOfWork publishedUnitOfWork, 
          IUnitOfWork unpublisedUnitOfWork) 
      : base(publishedUnitOfWork, unpublisedUnitOfWork) 
    { 
    } 
} 

Donc quand je demande et instance de IClaimRepository à partir de la carte de structure, je veux que l'implémentation reçoive l'unité d'objet de travail correcte, qui est essentiellement deux bases de données différentes, donc le même code avec différentes chaînes de connexion.

Répondre

1

N'a pas compilé et testé, mais il devrait fonctionner en principe:

For<IBar>.Add<PublicData>.Named("public"); 
For<IBar>.Add<PrivateData>.Named("private"); 

For<IFoo>.Use<Foo>() 
    .Ctor<IBar>("publicData").Is(d => d.TheInstanceNamed("public")) 
    .Ctor<IBar>("privateData").Is(d => d.TheInstanceNamed("private")); 

Edit: Pour ce faire, par convention, un IRegistrationConvention pourrait être utilisé

public class FooConvention : IRegistrationConvention 
{ 
    static readonly Type PluginType = typeof(IFoo); 

    public void Process(Type type, Registry registry) 
    { 
    if (type.IsAbstract || !type.IsClass || !PluginType.IsAssignableFrom(type)) 
     return; 

     registry.For(PluginType).Add(type) 
     .CtorDependency<IBar>("publicData") 
     .IsNamedInstance("public") 
     .CtorDependency<IBar>("privateData") 
     .IsNamedInstance("private"); 
    } 
} 

La convention être appliqué dans un balayage

Scan(scan => 
{ 
    scan.AssemblyContainingType<IFoo>(); 
    scan.Convention<FooConvention>(); 
} 

Voir le Scanning Assemblies section dans les documents SM pour plus d'informations.

+0

Existe-t-il un moyen de l'appliquer à un système basé sur des conventions? Je préfère ne pas avoir à câbler manuellement tous mes dépôts. – ilivewithian

+0

Voir ma modification pour une approche possible que j'ai utilisée. – PHeiberg

0

procéder à la configuration comme suit:

For<IFoo>.Use<Foo>(); 
For<IBar>.Use<IBar>(); 

obtenez alors les instances comme suit:

IBar privateData = ObjectFactory.GetInstance<IBar>(); 
IBar publicData = ObjectFactory.GetInstance<IBar>(); 

IFoo foo = ObjectFactory 
    .With<IBar>(publicData) 
    .With<IBar>(privateBar) 
    .GetInstance<IFoo>(); 

Ceci est juste une suggestion. Je suis corrigé :-)