Reputation: 5451
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([FooDB] 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?
Upvotes: 4
Views: 7147
Reputation: 7436
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.
Upvotes: 0
Reputation: 45445
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) { ... }
}
Upvotes: 9