Estou usando o Unity da Microsoft para injeção de dependência e quero fazer algo assim:
IDataContext context = _unityContainer.Resolve<IDataContext>();
var repositoryA = _unityContainer.Resolve<IRepositoryA>(context); //Same instance of context
var repositoryB = _unityContainer.Resolve<IRepositoryB>(context); //Same instance of context
IDataContext context2 = _unityContainer.Resolve<IDataContext>(); //New instance
var repositoryA2 = _unityContainer.Resolve<IRepositoryA>(context2);
RepositoryA
e RepositoryB
ambos têm um construtor que leva um IDataContext
parâmetro, e eu quero que o Unity inicialize o repositório com o contexto que passei. Observe também que IDataContext
não está registrado no Unity (não quero 3 instâncias de IDataContext
).
Foo(string name, int address) { ... }
container.Resolve<IFoo>(new ParameterOverrides { { "name", "bar" }, { "address", 42 } });
<2 centavos>
E se mais tarde você decidir usar um serviço diferente que requer mais ou menos do que apenas o contexto?
O problema com os parâmetros do construtor e IoC é que os parâmetros estão, em última análise, vinculados ao tipo concreto que está sendo usado, em vez de fazer parte do contrato que a interface de serviço define.
Minha sugestão seria que você resolvesse o contexto também, e eu acredito que o Unity deve ter uma maneira de evitar a construção de 3 instâncias dele, ou você deve considerar um serviço de fábrica que tem uma maneira para você construir o objeto.
Por exemplo, e se você mais tarde decidir construir um repositório que não dependa de um banco de dados tradicional, mas em vez disso use um arquivo XML para produzir dados fictícios para o teste? Como você alimentaria o conteúdo XML para esse construtor?
IoC é baseado em código de desacoplamento, amarrando o tipo e semântica dos argumentos aos tipos concretos, você realmente não fez o desacoplamento corretamente, ainda há uma dependência.
"Este código pode se comunicar com qualquer tipo de repositório, possivelmente, desde que implemente essa interface ... Ah, e use um contexto de dados".
Agora, eu sei que outros contêineres IoC têm suporte para isso, e eu o tinha em minha primeira versão também, mas na minha opinião, isso não pertence à etapa de resolução.
</ 2 centavos>
fonte
Obrigado galera ... o meu é parecido com o post do "Exist". Ver abaixo:
fonte
Você pode usar InjectionConstructor / InjectionProperty / InjectionMethod dependendo da sua arquitetura de injeção em ResolvedParameter <T> ("nome") para obter uma instância de um objeto pré-registrado no contêiner.
No seu caso, este objeto deve ser registrado com um nome, e para o mesmo caso, você precisa de ContainerControlledLifeTimeManager () como o LifeTimeManager.
fonte
Resolve
pega uma coleção deResolverOverride
eInjectionConstructor
não é umResolverOverride
.A resposta muito curta é: não. Atualmente, o Unity não tem como passar parâmetros para o construtor que não sejam constantes ou injetados, que eu consegui encontrar. IMHO, essa é a maior coisa que está faltando, mas acho que é por design, e não por omissão.
Como observa Jeff Fritz, você poderia, em teoria, criar um gerenciador de tempo de vida customizado que sabe qual instância de contexto injetar em vários tipos, mas esse é um nível de codificação que parece evitar o propósito de usar Unity ou DI em primeiro lugar.
Você poderia dar um pequeno passo para trás em relação ao DI completo e tornar as implementações de seu repositório responsáveis por estabelecer seus próprios contextos de dados. A instância de contexto ainda pode ser resolvida a partir do contêiner, mas a lógica para decidir qual usar teria que ir para a implementação do repositório. Certamente não é tão puro, mas acabaria com o problema.
fonte
Outra alternativa que você pode usar (não sei se é uma boa prática ou não) é criar dois contêineres e registrar uma instância para cada um:
espero que isso ajude também
fonte
NotDan, acho que você pode ter respondido sua própria pergunta em comentários para lassevk.
Primeiro, eu usaria um LifetimeManager para gerenciar o ciclo de vida e o número de instâncias de IDataContext que o Unity cria.
http://msdn.microsoft.com/en-us/library/cc440953.aspx
Parece que o
ContainerControlledLifetimeManager
objeto fornecerá o gerenciamento de instância de que você precisa. Com esse LifetimeManager em vigor, o Unity deve adicionar a mesma instância do IDataContext a todos os objetos que requerem uma dependência IDataContext.fonte