Я сделал небольшое приложение с, как мне кажется, нормальной многослойной архитектурой. https://github.com/mirypoko/Astoms Подскажите пожалуйста, может я что-то делаю не так? Может есть какие-то более хорошие подходы.
Есть несколько вопросов:
В данный момент существует множество подходов к созданию архитектуры MVC приложений (Domain Driven Design, 3d-layered architecture, onion structure, etc).
Мой любимый подход это 3х уровневая архитектура и вот почему:
Приложение ASP.NET MVC с этим подходом выглядело бы так:
Благодаря такой архитектуре изменения в одном уровне не повлекут за собой огромных изменений (а при правильном построении SOLID вообще не изменят другие слои).
Теперь по поводу реализации и вопросов:
PS. Под Generic Repository хорошо подходит реализация Generic UoW:
public interface IUnitOfWork : IDisposable
{
T GetRepository<T>() where T : class;
int Save();
}
public class UnitOfWork : IUnitOfWork
{
private Dictionary<string, object> _repositories;
private IDbContext _dbContext;
public UnitOfWork() : this(new AppContext())
{
}
public UnitOfWork(IDbContext dbContext)
{
_dbContext = dbContext;
_repositories = new Dictionary<string, object>();
}
/// <summary>
/// Search for repository in dictionary and if not exists creating new.
/// </summary>
/// <typeparam name="T">Type of repository to create.</typeparam>
/// <returns>Returns repository with DbContext provided by UoW.</returns>
public T GetRepository<T>() where T : class
{
if (!_repositories.ContainsKey(nameof(T)))
{
var repository = (T)Activator.CreateInstance(typeof(T), _dbContext);
_repositories.Add(nameof(T), repository);
}
return (T)_repositories[nameof(T)];
}
/// <summary>
/// Saves all pending changes.
/// </summary>
/// <returns>The number of objects in an Added, Modified, or Deleted state</returns>
public int Save()
{
return _dbContext.SaveChanges();
}
/// <summary>
/// Disposes current object.
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (disposing)
{
if (_dbContext != null)
{
_dbContext.Dispose();
_dbContext = null;
}
}
}
}
2.
Во-первых, DbContext
сам по себе является и репозиторием и единицей работы. Поэтому делать обёртки поверх него нет смысла. Имхо.
Статический UnitOfWork? Это как вообще? Смысл этого паттерна в том, что создаётся юнит, выполняется какая-то работа, закрывается юнит, что приводит к сохранению (или откату) данных, освобождению занятых ресурсов и т. п. То есть он никак не должен быть статическим.
3.
Как уже сказано выше, единица работы должна создаваться и удаляться по ходу работы. Реализовав интерфейс IDisposable
, можно использовать удобную конструкцию using
, что приведёт к закрытию юнита даже в случае исключений.
Но, как я уже сказал, DbContext
не нуждается в обёртках.
5. Их может быть сколько угодно. Например, один контекст может быть для работы с данными пользователей сайта, другой - для админов. Однако, чем их больше, тем тяжелее писать, а главное - поддерживать код.
Сделав несколько контекстов, намного сложнее осуществлять миграции! Спасибо tym32167 за напоминание.
Оборудование для ресторана: новинки профессиональной кухонной техники
Частный дом престарелых в Киеве: комфорт, забота и профессиональный уход
Пишу программу для парсинга одного сайта, использую AngleSharp библиотекуК сожалению документации не нашел, что усложняет процесс обучения
Создаю объект класса Action и как параметр передаю Driver,но почему-то на Driver выдаёт ошибку'Framework
Имеется необходимость на всём протяжении работы программы в некотором классе Watcher получать сообщения из некоего динамического буфера (Mailslot,...
Есть SPA-приложение со стэком MVC + WebAPI + Angular4Вот backend-маршруты: