Какой шаблон дизайна для размещения моего IUnitOfWork?
Вопрос
Я реализовал шаблон репозитория с незнанием постоянства.Реализация репозитория взаимодействует только с моими объектами entity, IUnitOfWork
и ITable<T>
интерфейсы.Намерение состоит в том, чтобы IUnitOfWork
не используется повторно, а представляет собой единую транзакцию.До сих пор я реализовал версии in-memory, а также Linq-to-Sql для IUnitOfWork
и ITable<T>
.
Моя проблема заключается в том, что из-за IUnitOfWork
внедрение в репозиторий, в конечном итоге мне нужно знать, как создать экземпляр нового IUnitOfWork
где бы ни использовался репозиторий.Поскольку это основная часть, которая должна быть подключаемой, мне кажется, что я сделал что-то не так.Общий шаблон использования выглядит примерно так:
FooUnitOfWork unitOfWork = new FooUnitOfWork();
Repository repos = new Repository(unitOfWork);
// ...act upon repos
unitOfWork.Save();
Теперь, похоже, мне нужен какой-то другой шаблон, позволяющий при каждом использовании репозитория в приложении получать правильную единицу работы (напримервстроенная память, L2S и т.д.).
Какой шаблон наиболее подходит для этого? Я просмотрел на Обсуждение Фаулером этой темы но ни один из его примеров, похоже, не подходит полностью.Я уже чувствую, что объем абстракции, который у меня есть, больше, чем хотелось бы, поэтому создание еще одной косвенности кажется чрезмерным.
На данный момент я склоняюсь к какому-то провайдеру для всего приложения, который может быть настроен для создания правильного IUnitOfWork
.Я не на базе или это то, что нужно, чтобы действительно быть независимым от реализации?
Решение
Обновить: хотя на самом деле это не сломалось, в итоге получился просто контейнер IoC для бедных.В итоге я просто заменил все это:
UnitOfWorkFactory.Create();
с обобщенным Общий Служебный Локатор реализация:
Microsoft.Practices.ServiceLocation.ServiceLocator.Current.GetInstance<IUnitOfWork>();
Это позволило мне создать библиотеку, которая использует внедрение зависимостей, не заставляя всех пользователей использовать один и тот же фреймворк IoC.
Возможно, мне следует использовать очень простую фабрику, где я могу установить обратный вызов?В нем мог бы быть набор статических методов, подобных этому:
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;
}
}
Где это происходит?
Другие советы
Я бы предложил использовать шаблон Vistor для ознакомления с реализациями интерфейса IUnitOfWork.
[UnitOfWork(Name="foo")]
public class FooUnitOfWork : IUnitOfWork {}
Repository repo = new Repository("foo");
//stuff happens
repo.Save(); //or repo.Worker.Save();
Внутри экземпляра репозитория фабрика обнаружения находит рабочего и создает его.