I'm using Autofac. I want to inject a different implementation of a dependency based on an attribute I apply to the constructor parameter. For example:
class CustomerRepository
{
public CustomerRepository([CustomerDB] IObjectContainer db) { ... }
}
class FooRepository
{
public FooRepository([开发者_如何学CFooDB] IObjectContainer db) { ... }
}
builder.Register(c => /* return different instance based on attribute on the parameter */)
.As<IObjectContainer>();
The attributes will be providing data, such as a connection string, which I can use to instance the correct object.
How can I do this?
It sounds like you want to provide different implementations of IObjectContainer
to CustomerRepository
and FooRepository
. If that is the case, attributes might be a thin metal ruler. Instead, I'll show you how I would implement multiple implementations with Autofac.
(Calls such as .ContainerScoped()
have been left out for brevity.)
First, register a version of IObjectContainer
for each connection string by naming the registrations:
builder
.Register(c => new ObjectContainer(ConnectionStrings.CustomerDB))
.As<IObjectContainer>()
.Named("CustomerObjectContainer");
builder
.Register(c => new ObjectContainer(ConnectionStrings.FooDB))
.As<IObjectContainer>()
.Named("FooObjectContainer");
Then, resolve the specific instances in the repository registrations:
builder.Register(c => new CustomerRepository(
c.Resolve<IObjectContainer>("CustomerObjectContainer"));
builder.Register(c => new FooRepository(
c.Resolve<IObjectContainer>("FooObjectContainer"));
This leaves the repositories free of configuration information:
class CustomerRepository
{
public CustomerRepository(IObjectContainer db) { ... }
}
class FooRepository
{
public FooRepository(IObjectContainer db) { ... }
}
Bryan's answer is good enough while you have several repositories and they have few constructor parameters. But it is difficult to set up your root when you have many of them. You can achieve this by scanning your class metadata on resolving an interface. When you get info about its parameters you can resolve actual implementation of it. See my answer here.
精彩评论