Resolva a dependência com o Autofac com base no atributo do parâmetro do construtor

StackOverflow https://stackoverflow.com/questions/2477613

  •  21-09-2019
  •  | 
  •  

Pergunta

Estou usando Autofac. Quero injetar uma implementação diferente de uma dependência com base em um atributo que aplico ao parâmetro construtor. Por exemplo:

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>();

Os atributos fornecerão dados, como uma string de conexão, que posso usar para instância do objeto correto.

Como posso fazer isso?

Foi útil?

Solução

Parece que você deseja fornecer implementações diferentes de IObjectContainer para CustomerRepository e FooRepository. Se for esse o caso, os atributos podem ser um régua de metal fino. Em vez disso, mostrarei como implementaria várias implementações com o Autofac.

(Chamadas como .ContainerScoped() foram deixados de fora para a brevidade.)

Primeiro, registre uma versão de IObjectContainer Para cada string de conexão, nomeando os registros:

builder
    .Register(c => new ObjectContainer(ConnectionStrings.CustomerDB))
    .As<IObjectContainer>()
    .Named("CustomerObjectContainer");

builder
    .Register(c => new ObjectContainer(ConnectionStrings.FooDB))
    .As<IObjectContainer>()
    .Named("FooObjectContainer");

Em seguida, resolva as instâncias específicas nos registros do repositório:

builder.Register(c => new CustomerRepository(
    c.Resolve<IObjectContainer>("CustomerObjectContainer"));

builder.Register(c => new FooRepository(
    c.Resolve<IObjectContainer>("FooObjectContainer"));

Isso deixa os repositórios livres de informações de configuração:

class CustomerRepository
{
    public CustomerRepository(IObjectContainer db) { ... }
}

class FooRepository
{
    public FooRepository(IObjectContainer db) { ... }
}

Outras dicas

A resposta de Bryan é boa o suficiente enquanto você tem vários repositórios e eles têm poucos parâmetros do construtor. Mas é difícil configurar sua raiz quando você tem muitos deles. Você pode conseguir isso digitalizando seus metadados de classe na resolução de uma interface. Quando você obtém informações sobre seus parâmetros, pode resolver a implementação real dele. Veja minha resposta aqui.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top