Луковая архитектура, единица работы и общий шаблон репозитория

Это первый раз, когда я внедряю более ориентированный на домен подход. Я решил попробоватьЛуковая Архитектура поскольку он фокусируется на домене, а не на инфраструктуре / платформах / и т.д.

Чтобы абстрагироваться от Entity Framework, я создалобщий репозиторий сЕдиница работы реализация.

IRepository<T> а такжеIUnitOfWork интерфейсы:

public interface IRepository<T>
{
    void Add(T item);

    void Remove(T item);

    IQueryable<T> Query();
}

public interface IUnitOfWork : IDisposable
{
    void SaveChanges();
}

Реализация Entity FrameworkIRepository<T> а такжеIUnitOfWork:

public class EntityFrameworkRepository<T> : IRepository<T> where T : class
{
    private readonly DbSet<T> dbSet;

    public EntityFrameworkRepository(IUnitOfWork unitOfWork)
    {
        var entityFrameworkUnitOfWork = unitOfWork as EntityFrameworkUnitOfWork;

        if (entityFrameworkUnitOfWork == null)
        {
            throw new ArgumentOutOfRangeException("Must be of type EntityFrameworkUnitOfWork");
        }

        dbSet = entityFrameworkUnitOfWork.GetDbSet<T>();
    }

    public void Add(T item)
    {
        dbSet.Add(item);
    }

    public void Remove(T item)
    {
        dbSet.Remove(item);
    }

    public IQueryable<T> Query()
    {
        return dbSet;
    }
}

public class EntityFrameworkUnitOfWork : IUnitOfWork
{
    private readonly DbContext context;

    public EntityFrameworkUnitOfWork()
    {
        this.context = new CustomerContext();;
    }

    internal DbSet<T> GetDbSet<T>()
        where T : class
    {
        return context.Set<T>();
    }

    public void SaveChanges()
    {
        context.SaveChanges();
    }

    public void Dispose()
    {
        context.Dispose();
    }
}

Покупатель репозиторий:

public interface ICustomerRepository : IRepository<Customer>
{

}

public class CustomerRepository : EntityFrameworkRepository<Customer>, ICustomerRepository 
{
    public CustomerRepository(IUnitOfWork unitOfWork): base(unitOfWork)
    {
    }
}

ASP.NET MVC контроллер с использованием репозитория:

public class CustomerController : Controller
{
    UnityContainer container = new UnityContainer();

    public ActionResult List()
    {
        var unitOfWork = container.Resolve<IUnitOfWork>();
        var customerRepository = container.Resolve<ICustomerRepository>();

        return View(customerRepository.Query());
    }

    [HttpPost]
    public ActionResult Create(Customer customer)
    {
        var unitOfWork = container.Resolve<IUnitOfWork>();
        var customerRepository = container.Resolve<ICustomerRepository>();; 

        customerRepository.Add(customer);

        unitOfWork.SaveChanges();

        return RedirectToAction("List");
    }
}

Внедрение зависимости с единицей:

container.RegisterType<IUnitOfWork, EntityFrameworkUnitOfWork>();
container.RegisterType<ICustomerRepository, CustomerRepository>();

Решение:

ПРОБЛЕМЫ?

Реализация репозитория (код EF) очень общая. Все это сидит в стороне отEntityFrameworkRepository<T> класс. Конкретные репозитории моделей не содержат никакой этой логики. Это спасает меня от написания тонны избыточного кода, но, возможно, жертвует гибкостью?

ICustomerRepository а такжеCustomerRepository, классы в основном пустые. Они просто для того, чтобы обеспечить абстракцию. Насколько я понимаю, это согласуется с концепцией Onion Architecture, где инфраструктура и зависимый от платформы код находятся за пределами вашей системы, но наличие пустых классов и пустых интерфейсов кажется неправильным?

Чтобы использовать другую реализацию персистентности (скажем, хранилище таблиц Azure), затем новуюCustomerRepository класс должен быть создан и будет наследоватьAzureTableStorageRepository<T>, Но это может привести к избыточному коду (несколько CustomerRepositories)? Как бы этот эффект издевался?

Другая реализация (скажем, хранилище таблиц Azure) имеет ограничения по транснациональной поддержке, поэтому класс AzureTableStorageUnitOfWork не будет работать в этом контексте.

Есть ли другие проблемы с тем, как я это сделал?

(Я взял большую часть моего вдохновения отэта почта)

Ответы на вопрос(3)

Ваш ответ на вопрос