Я создаю API-интерфейс библиотеки классов, который обертывает бизнес-логику и доступ к базе данных SQL Server через Entity Framework 6.Шаблон проектирования для точки входа API?
Я разработал ее с использованием модуля работы и шаблонов репозитория. Целью является упрощение использования и модульного тестирования.
Бизнес-логика и проверка выполняются на сервисном уровне. Я не буду использовать контейнер IOC, потому что чувствую, что это усложнит использование API .
Проект имеет 15 хранилищ и услуг
Текущий дизайн выглядит следующим образом:
Service Layer A -> Единица работы -> Repository А и или B
Service Layer B -> Единица работа -> Repository B или а и ...
...
public class ServiceA : IServiceA, IService
{
private readonly IUnitOfWork unitOfWork;
public AssetService(IUnitOfWork unitOfWork)
{
this.unitOfWork = unitOfWork;
}
...
public IList<DomainObjectA> GetAll()
{
return unitOfWork.RepositoryA.GetAll();
}
public void Dispose()
{
unitOfWork.Dispose();
}
...
}
public class UnitOfWork : IUnitOfWork
{
private readonly MyDbContext context = new MyDbContext();
private IRepositoryA repositoryA;
private IRepositoryB repositoryB;
...
public IRepositoryA RepositoryA
{
get { return repositoryA = repositoryA ?? new RepositoryA(context); }
}
public IRepositoryB RepositoryB
{
get { return repositoryB = repositoryB ?? new RepositoryB(context); }
}
...
public void Save()
{
context.SaveChanges();
}
public void Dispose()
{
context.Dispose();
}
}
public class RepositoryA : Repository, IRepositoryA
{
public RepositoryA(MyDbContext context)
: base(context) {}
public IList<DomainObjectA> GetAll()
{
return context.tblA.ToList().Select(x => x.ToDomainObject()).ToList();
}
...
}
Поскольку это API, который должен быть использован в других проектах, мне нужен хороший и «честно» легко т o использовать интерфейс для пользователя, который использует API. Из-за этого модуль UnitOfWork создается в этом «общедоступном интерфейсе» между пользователем и уровнем сервиса, см. Ниже.
Я также считаю, что лучше всего использовать инструкцию using в API, чтобы db-контекст располагался правильно и сразу после каждого вызова службы.
Я начал с использованием прокси-шаблона для этого: Примера:
public class ProxyA : Proxy, IServiceA
{
public IList<DomainObjectA> GetAll()
{
using (var service = GetService<ServiceA>())
return service.GetAll();
}
...
}
public abstract class Proxy
{
protected T GetService<T>() where T : IService
{
return (T)Activator.CreateInstance(typeof(T), new object[] { new UnitOfWork()});
}
}
Но это потребовало бы мне создать прокси-сервер для каждого сервиса. Я мог бы, конечно, пропустить интерфейс службы в прокси и создать общий прокси-сервер, который обрабатывает все службы.
Я также рассмотрел шаблон «Фасад», но не могу решить, какой шаблон использовать для этого конкретного сценария.
Мои вопросы:
Является ли это хорошим подходом или есть какие-либо другие шаблоны проектирования, которые позволят решить эту проблему?
Также должна быть одна публичная точка входа API или несколько, сгруппированных по какой-либо бизнес-логике?
Так вы говорите, создать меньше сервисов (groupd по бизнес-логике) вместо одного для каждого репозитория, а затем сохранить шаблон прокси (один прокси для каждой службы) как фронт api? Я думаю, что мне нравится этот подход лучше, чем создание жирного класса фасадов, который содержит все доступные методы api ... – ThePike
Да, это подход, который я обычно использую. Проблема с созданием толстого фасада заключается в том, что по мере роста приложения вы можете завершить слишком много методов в одном классе. – TonyS