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 :-)
精彩评论