Шаблон репозитория с Linq to SQL с использованием IoC, внедрения зависимости, единицы работы - PullRequest
6 голосов
/ 26 октября 2009

Кажется, есть много примеров реализации шаблона репозитория для Linq to SQL. Большинство из них имеют IRepository и DI; Некоторые внедрили Единицу работы, а некоторые нет. Я попытался прочитать, так как большинство результатов, возвращаемых поисками в SO и Google в шаблонах репозитория Linq to SQL. Тем не менее, я еще не нашел полного решения.

Из моих чтений я реализовал шаблон хранилища, как показано ниже:

repository pattern

Я использую DI для регистрации интерфейсов, от которых зависят репозитории:

this.container.RegisterType<IConnectionStringFactory, ConnectionStringFactory>(new ContainerControlledLifetimeManager(),
    new InjectionConstructor(connectionString));
this.container.RegisterType<IDataContextFactory, DataContextFactory>();

Реализация шаблона репозитория:

public interface IPrivilegeRepository : IRepository<PrivilegesEntity>
{
   IList<MenuModel> GetRootMenu();
   IList<MenuModel> GetChildMenu(int parentId);
}

public class PrivilegeRepository : Repository<PrivilegesEntity>, IPrivilegeRepository
{
    #region IPrivilegeRepository Members

    public IList<MenuModel> GetRootMenu()
    {
        return FindAll(menu => menu.ParentId == null)
            .OrderBy(menu => menu.SortOrder)
            .Select(c => EntityMapper.Privileges.ToBusinessObject(c))
            .ToList();
    }

    public IList<MenuModel> GetChildMenu(int parentId)
    {
        return FindAll(menu => menu.ParentId == parentId)
            .OrderBy(menu => menu.SortOrder)
            .Select(menu => EntityMapper.Privileges.ToBusinessObject(menu))
            .ToList();
    }

    #endregion

    public PrivilegeRepository(IDataContextFactory dataContextFactory)
        : base(dataContextFactory)
    {
    }
}

Общий интерфейс репозитория:

public interface IRepository<T> where T : class
{
    IEnumerable<T> All();
    IEnumerable<T> FindAll(Expression<Func<T, bool>> exp);
    T Single(Expression<Func<T, bool>> exp);
    T First(Expression<Func<T, bool>> exp);
}

Класс репозитория реализован, как показано ниже, с реализациями IRepository (не показаны) и имеет зависимость от IDataContextFactory, о которой заботится DI:

public class Repository<T> : IRepository<T> where T : class
{
    public Repository(IDataContextFactory dataContextFactory)
    {
        this.dataContextFactory = dataContextFactory;
    }
}

Репозитории используются с использованием IoC:

PrivilegeRepository repository = container.Resolve<PrivilegeRepository>();

Я возвращаю результат запросов в виде коллекции Business Object, чтобы избежать зависимости от Linq to SQL на прикладных уровнях, где я использую репозиторий. Приведенный выше сценарий прекрасно работает с моим приложением WPF, использующим шаблон MVVM. У меня есть ViewModel aks Presenter классы, которые не зависят от классов, сгенерированных Linq-SQL.

Как расширить этот шаблон, чтобы я мог сохранять данные в базе данных. Я хотел бы передать Business Objects обратно в хранилище и сохранить их. Является ли это возможным? Как я могу реализовать Unit of Work в таком сценарии.

Ответы [ 2 ]

5 голосов
/ 12 августа 2011

Вот мой ответ на аналогичный вопрос.

Основная идея заключается в том, что универсальный репозиторий интерфейсы работает не так хорошо, но универсальный репозиторий реализации прекрасно работает. Он использует LINQ to SQL в качестве примера ORM и должен дать некоторое представление о вашем вопросе.

Обязательно прочитайте и ответ Павла, особенно комментарии.

1 голос
/ 11 августа 2011

Ну, это проблема, которую я видел много раз. Вы хотите отделить бизнес-объекты от стратегии хранения данных. Когда вы выполняете проекцию на свои бизнес-объекты, вы теряете много приятных особенностей наличия репозитория (вы можете вернуть IQueryable, например, используя отложенное выполнение). Единственный способ реализовать это - дать вашему репозиторию зависимость, например, от IMapper<BusinessObject>. Таким образом, вы можете отобразить свой бизнес-объект на объект, который нужен вашему репозиторию, чтобы что-то сохранить, но оставить абстракцию на месте, поскольку ваши бизнес-объекты остаются невежественными.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...