开发者

How do I use sturcturemap to pass two different implementations of a single interface into a constructor?

I have a constructor that take two interfaces, they are the same interface, but need to be different implementations:

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

What I'd like to happen is that structuremap would pass in a concrete implementation of IBar as class PublicData and class PrivateData for the different arguments. Is this possible?

UPDATE

In fact, to make sure there is enough information:

The real classes that I'm working with look like this:

public abstract class EFRepository<T> : IR开发者_Python百科epository<T>
{
    protected EFRepository(IUnitOfWork publicUnitOfWork, 
                           IUnitOfWork privateUnitOfWork)
    {

    }
}

And an implementation of EFRepository might look like this:

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

So when I request and instance of IClaimRepository from structure map I want the implementation to be given the correct unit of work objects, which in my instance are essentially two different databases, so it's the same code with different connection strings.


Haven't compiled and tested, but it should work in principle:

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: For making this by convention an IRegistrationConvention could be used

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

The convention would be applied in a scan

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

See the Scanning Assemblies section in the SM docs for further info.


Setup the configuration as follows:

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

Then get the instances as follows:

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

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

This is just a suggestion. I stand corrected :-)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜