Шаблон репозитория: один класс репозитория для каждой сущности? - PullRequest
26 голосов
/ 19 августа 2010

Скажем, у вас есть следующие сущности, определенные в классе LINQ:

Product
Customer
Category

Должен ли я иметь один класс хранилища для всех:

StoreRepository

... или я должен иметь:

ProductRepository
CustomerRepository
CategoryRepository

Каковы плюсы и минусы каждого?В моем случае у меня есть несколько «приложений» в моем решении ... Приложение Store - только одно из них.

Ответы [ 4 ]

19 голосов
/ 19 августа 2010

Вот моя точка зрения. Я строгий последователь шаблона Repository. Там должно быть 3 метода, которые принимают одну сущность. Добавить, Обновить, Удалить, определено в общем.

public interface IRepository<T>
{
     void Add(T entity);
     void Update(T entity);
     void Delete(T entity);
}

Помимо этих методов, вы имеете дело с «запросом» или методом обслуживания. Если бы я был на вашем месте, я бы сделал хранилище в общем виде, как указано выше, добавив «QueryProvider», как показано ниже, и поместил вашу бизнес-логику , где он принадлежит , в «Службы» или в «Команды» / Запросы "(исходит из CQRS, Google it) .

public interface IQueryProvider<T>
{
     TResult Query<TResult>(Func<IQueryable<T>, TResult> query);
}

(Надеюсь, мое мнение несколько полезно :))

5 голосов
/ 19 августа 2010

Все зависит от того, каким будет «Доменно-управляемый дизайн».Вы знаете, что такое Совокупный Корень?В большинстве случаев достаточно использовать общий тип CRUD для выполнения всех ваших базовых CRUD.Только когда вы начинаете иметь толстые модели с контекстом и границами, это начинает иметь значение.

1 голос
/ 21 августа 2010

Как правило, будет один репозиторий для каждого корневого объекта.В книге ASP.NET MVC 2 в действии есть несколько интересных моментов, касающихся DDD и совокупного корневого объекта, а также того, как мы должны проектировать классы хранилища.

0 голосов
/ 24 августа 2010

У меня был бы один репозиторий / объект, потому что неизменно должна быть карта из моего EntityTable в мой объект домена (например, в теле GetIQueryableCollection (). Как мне удалось написать этот повторяющийся код, так этосделав шаблон T4 для его генерации.

У меня есть пример проекта, который генерирует шаблон репозитория на codeplex http://t4tarantino.codeplex.com/ Пример T4 Toolbox Шаблоны для бизнес-классов и репозитория. Он может работать не совсем точнобез каких-либо настроек, если только вы не внедрили Tarintino и несколько других полезностей, но шаблоны легко настраиваются.

using System;
using System.Collections.Generic;
using System.Linq;
using Cses.Core.Domain.Model;
using StructureMap;

namespace Cses.Core.Domain
{
    /// <summary>
    /// Core class for Schedule E
    /// </summary>
    public class ScheduleERepository : IScheduleERepository
    {

        private Cses.Core.Repository.SqlDataContext _context = new Cses.Core.Repository.SqlDataContext();

        /// <summary>
        /// constructor
        /// </summary>
        public ScheduleERepository() { }

        /// <summary>
        /// constructor for testing
        /// </summary>
        /// <param name="context"></param>
        public ScheduleERepository(Cses.Core.Repository.SqlDataContext context)
        {
            _context = context;

        }

        /// <summary>
        /// returns collection of scheduleE values
        /// </summary>
        /// <returns></returns>
        public IQueryable<ScheduleE> GetIQueryableCollection()
        {           
            return from entity in _context.ScheduleEs                  
               select new ScheduleE()
               {    
                    Amount = entity.Amount,
                    NumberOfChildren = entity.NumberChildren,
                    EffectiveDate = entity.EffectiveDate,
                    MonthlyIncome = entity.MonthlyIncome,
                    ModifiedDate = entity.ModifiedDate,
                    ModifiedBy = entity.ModifiedBy,                      
                    Id = entity.Id                          
               };           
        }
...