문제

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?

도움이 되었습니까?

해결책

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.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top