Я создал инфраструктуру нашего совершенно нового интранет-проекта и старался следовать почти всем передовым методам. Также я хочу отметить, что это мой первый опыт создания архитектуры с нуля.
В настоящее время первая версия моей инфраструктуры готова и хорошо работает. Но я хочу реализовать структуру ограниченного контекста в следующей версии.
Я попытался объяснить текущую ситуацию следующим образом.
DbCore: отвечает за операции с данными. Код Entity Framework 5 Впервые использован. Существует только один класс DbContext и все DbSet, определенные в нем. Также шаблон GenericRepository и шаблон Unit of Work реализованы на основе следующих интерфейсов.
IGenericRepository
public interface IGenericRepository<TEntity>
where TEntity : class {
void Delete(object id);
void Delete(TEntity entityToDelete);
System.Collections.Generic.IEnumerable<TEntity> Get(System.Linq.Expressions.Expression<Func<TEntity, bool>> filter = null, Func<System.Linq.IQueryable<TEntity>, System.Linq.IOrderedQueryable<TEntity>> orderBy = null, string includeProperties = "");
System.Collections.Generic.IEnumerable<TEntity> GetAll();
TEntity GetByID(object id);
System.Collections.Generic.IEnumerable<TEntity> GetWithRawSql(string query, params object[] parameters);
void Insert(TEntity entity);
void Update(TEntity entityToUpdate);
}
IUnitOfWork
public interface IUnitOfWork {
void Dispose();
IGenericRepository<Test> TestRepository {
get;
}
IGenericRepository<Log> LogRepository {
get;
}
void Save();
}
Модели: ответственное хранение моделей сущностей для DbCore и Entity Framework. Домен: уровень бизнес-логики представления также хранит DTO для объектов сущностей, которые хранятся в проекте Models. В настоящее время бизнес-логика хранится в классе Service, который реализует следующий интерфейс IService.
public interface IService<TEntity> {
IEnumerable<TEntity> Get();
TEntity GetByID(int id);
void Insert(TEntity entity);
}
Этот класс обслуживания получает UnitOfWork через параметр ctor и использует его для операций. Также Automapper реализован для преобразования объектов сущностей в DTO или наоборот. Отныне все верхние уровни больше не интересуются моделями сущностей, а используют только DTO. Так что почти все проекты (включая API и веб) ссылаются на этот проект.
Общие. Отвечает за хранение часто используемых библиотек, таких как ведение журналов.
WebCore. Отвечает за хранение часто используемых библиотек для веб-проектов, таких как API или MVC. Также содержит расширения, обработчики и фильтры для проектов на основе MVC.
Api: проект веб-API ASP.Net MVC представляет уровень службы. Использует уровень домена и обслуживает клиентов. Контроллеры получают интерфейс IService в качестве параметра ctor и используют его для доступа к уровню данных через уровень домена.
Интернет: веб-проект на основе ASP.Net MVC 4, отвечающий за взаимодействие с пользователем. Использует методы API для доступа к данным. Все контроллеры получают интерфейс с именем IConsumeRepository, который подключается к API через HttpClient.
public interface IConsumeRepository<TEntity> {
Task<TEntity> Create(TEntity TestInfo);
Task Delete(int id);
Task<IEnumerable<TEntity>> Get();
Task<TEntity> Get(int id);
TEntity New();
Task<TEntity> Update(TEntity TestInfo, int entityId);
}
Autofac отвечает за IoC и DI для всех проектов.
На данный момент это моя текущая инфраструктура, я думаю, что объяснил все, что нужно оценить.
Теперь я пытаюсь выяснить следующие вещи,
Вопрос 1: Есть ли что-то, что НЕ ДОЛЖНО быть реализовано так, как я использовал?
Вопрос 2. Каков наилучший подход к реализации ограниченных контекстов? Недавно я посмотрел видео Джули Лерман и просмотрел множество примеров проектов. Обычная вещь, которую я видел, получая BC от DbContext. Но я не мог быть уверен. Потому что я думал, что BC должны быть на уровне домена (бизнес-логика), а не на уровне DbCore (доступ к данным).
Вопрос 3: Как я уже упоминал выше, мои проекты API и веб-сайтов используют DTO, поэтому оба они должны иметь уровень ссылок на домен. Но мне это не понравилось, потому что я отделяю бизнес-уровень от пользовательского интерфейса с помощью API и снова соединяю их для сущностей. Но я не мог найти ничего лучше, чем этот.
Это стало длинным вопросом, но я буду очень рад, если вы поделитесь со мной своими идеями по созданию лучшей архитектуры.