Como faço para implementar uma fábrica delegada?
-
21-09-2019 - |
Pergunta
A documentação para Autofac tem uma página interessante que descreve sua capacidade de gerar automaticamente delegado fábricas. Também sugere fortemente que você pode obter resultados semelhantes sem o Autofac escrevendo -os manualmente.
Estou usando o Unity para o COI e gostaria de evitar passar o contêiner para objetos que precisam criar outros objetos; portanto, como você escreveria uma fábrica delegada sem autofac?
Solução
Bem, eu nunca usei a unidade até agora, então minha resposta é bastante vaga.
O diretor é simples. Você define alguns delegados que representam fábricas. Em seguida, você cria uma classe 'fábrica' que possui métodos públicos que correspondem aos delegados. Esta classe conhece o contêiner. Agora você registra o delegado e define essa classe como implementação. Então você pode injetar apenas o delegado. Quando você chama o delegado injetado, a classe de fábrica é chamada, que conhece o contêiner e pede uma nova instância ao contêiner.
Primeiro, você define seus delicios de fábrica.
public delegate TServiceType Provider<TServiceType>();
public delegate TServiceType Provider<TArg,TServiceType>(TArg argument);
Você cria uma fábrica genérica:
/// <summary>
/// Represents a <see cref="Provider{TArg,TServiceType}"/> which holds
/// the container context and resolves the service on the <see cref="Create"/>-call
/// </summary>
internal class GenericFactory{
private readonly IContainer container;
public ClosureActivator(IContainer container)
{
this.container= container;
}
/// <summary>
/// Represents <see cref="Provider{TServiceType}.Invoke"/>
/// </summary>
public TService Create()
{
return container.Resolve<TService>();
}
/// <summary>
/// Represents <see cref="Provider{TArg,TServiceType}.Invoke"/>
/// </summary>
public TService Create(TArg arg)
{
return container.Resolve<TService>(new[] {new TypedParameter(typeof (TArg),arg)});
}
}
Agora, o que você registra o delegado, algo assim:
var newServiceCreater = new GenericFactory(container);
container.Register<Provider<MyCompoent>>().To(newServiceCreater.Create);
var newServiceCreater = new GenericFactory(container);
container
.Register<Provider<OtherServiceWithOneArgumentToConstruct>>()
.To(newServiceCreater.Create);
Agora, outro você injeta para outros componentes apenas o 'provedor' em vez do contêiner.