Qual padrão de design para localizar meu iunitofwork?
Pergunta
Eu implementei um padrão de repositório com ignorância de persistência. A implementação do repositório apenas interage com meus objetos de entidade, IUnitOfWork
e ITable<T>
interfaces. A intenção é que o IUnitOfWork
não é reutilizado, mas representa uma única transação. Até agora, implementei versões na memória e linq-to-sql do IUnitOfWork
e ITable<T>
.
Meu problema é que devido ao IUnitOfWork
Injeção no repositório, acabo precisando saber como instanciar um novo IUnitOfWork
Onde sempre o repositório é usado. Como esta é a peça principal que deveria ser flugable, parece que eu fiz algo errado. O padrão de uso geral é algo assim:
FooUnitOfWork unitOfWork = new FooUnitOfWork();
Repository repos = new Repository(unitOfWork);
// ...act upon repos
unitOfWork.Save();
Agora parece que preciso de algum outro padrão para permitir que todo uso do repositório no aplicativo obtenha a unidade de trabalho correta (por exemplo, na memória, L2s, etc.).
Qual é o padrão mais adequado para isso? Eu olhei Discussão de Fowler sobre o tópico Mas nenhum de seus exemplos parece ser um ajuste limpo. Eu já sinto que a quantidade de abstração que tenho é mais do que gostaria, para que construir mais uma indireção parece excessiva.
No momento, estou inclinado para algum tipo de provedor em todo o aplicativo que pode ser configurado para produzir o correto IUnitOfWork
. Estou fora da base ou é isso que é necessário para ser realmente agnóstico?
Solução
Atualizar: Embora isso realmente não tenha quebrado, acabou apenas produzindo o contêiner do Poor Man. Acabei apenas substituindo tudo isso:
UnitOfWorkFactory.Create();
com o generalizado Localizador de serviço comum implementação:
Microsoft.Practices.ServiceLocation.ServiceLocator.Current.GetInstance<IUnitOfWork>();
Isso me permitiu criar uma biblioteca que use injeção de dependência sem forçar todos os usuários a usar a mesma estrutura do COI.
Talvez eu deva usar uma fábrica muito simples, onde possa definir um retorno de chamada? Pode ter um conjunto de métodos estáticos assim:
public static class UnitOfWorkFactory
{
private static Func<IUnitOfWork> FactoryMethod;
public static IUnitOfWork Create()
{
if (UnitOfWorkFactory.FactoryMethod == null)
{
throw new InvalidOperationException("...");
}
return UnitOfWorkFactory.FactoryMethod();
}
public static void SetFactoryMethod(Func<IUnitOfWork> factory)
{
UnitOfWorkFactory.FactoryMethod = factory;
}
}
Onde isso quebra?
Outras dicas
Eu sugeriria o uso de um padrão de Vistor para descobrir as implementações da interface iunitofwork.
[UnitOfWork(Name="foo")]
public class FooUnitOfWork : IUnitOfWork {}
Repository repo = new Repository("foo");
//stuff happens
repo.Save(); //or repo.Worker.Save();
Dentro da instância do repo, uma fábrica de descoberta encontra o trabalhador e a cria.