Как я могу реализовать единицу работы и шаблон репозитория для статического класса?
Вы можете использовать тот факт, что всякий раз, когда кто-то вызывает код здесь, он делает это через публичная точка входа .Это означает, что когда вызывающий объект впервые входит в класс (с помощью указанного открытого метода), вы создаете единицу работы и утилизируете ее только тогда, когда тот же метод возвращает значение вызывающему элементу (или просто завершается).
Что-то вроде:
public static class MyClass
{
public static User LoadUser(int userId)
{
using (var uow = new UnitOfWork())
{
DoSomething(uow);
var user = uow.UserRepository.GetById(userId);
return user;
}
}
}
По сути, каждый публичный метод должен создавать, использовать и распоряжаться одним экземпляром единицы работы.Это обеспечивает две вещи:
- Параллельные вызовы используют свою собственную отдельную единицу работы.
- Никакая единица работы никогда не задержится в памяти после завершения метода ввода.
Это становится сложнее, когда вы начинаете использовать асинхронное программирование, но я опускаю это соображение, так как вы никогда не упоминали об этом.
Мне нравится реализовывать решение, применяянадежные принципы и тестируемое приложение
Это становится немного сложнее, когда вы имеете дело с внедрением зависимостей.Статические классы не имеют конструктора для инъекций (примечание: у них есть конструктор, но они не допускают аргументов конструктора).
Таким образом, внедрение вашей зависимости будет ... нетипичным.Одно из решений, которое я могу придумать, - это явно установить ядро (я использую здесь NInject в качестве примера):
public static class MyClass
{
public static IKernel Kernel { get; set; }
public static User LoadUser(int userId)
{
using (var uow = Kernel.Get<IUnitOfWork>())
{
DoSomething(uow);
var user = uow.UserRepository.GetById(userId);
return user;
}
}
}
Как вы устанавливаете ядро (либо устанавливая его явно, либо назначая его по умолчанию)ценность напрямую) зависит от вас.
Без NInject или любой другой подобной библиотеки вы можете добиться внедрения зависимости, используя Func<IUnitOfWork>
в качестве заводского метода для создания единицы работы по требованию:
public static class MyClass
{
public static Func<IUnitOfWork> CreateUnitOfWork { get; set; }
public static User LoadUser(int userId)
{
using (var uow = CreateUnitOfWork())
{
DoSomething(uow);
var user = uow.UserRepository.GetById(userId);
return user;
}
}
}
Опять же, как вы устанавливаетезаводской метод зависит от вас, например:
MyClass.CreateUnitOfWork = () => new UnitOfWork();