使用IoC,依赖注入,工作单元使用Linq to SQL的存储库模式

时间:2009-10-26 11:10:57

标签: linq-to-sql dependency-injection inversion-of-control repository-pattern unit-of-work

似乎有很多关于为Linq to SQL实现Repository模式的例子。其中大部分都是IRepository和DI;有些人实施了工作单位,有些则没有。我尝试阅读在SO和Google上搜索Linq到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)
    {
    }
}

IRepository通用接口:

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);
}

Repository类通过IRepository(未显示)的实现实现如下,并且依赖于DI正在处理的IDataContextFactory:

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。上面的场景适用于我使用MVVM模式的WPF应用程序。我有ViewModel aks Presenter类,它们不依赖于Linq-SQL生成的类。

如何扩展此模式以便将数据保存到数据库。我想将Business Objects传递回存储库并保存它们。可能吗?如何在这种情况下实施工作单元。

2 个答案:

答案 0 :(得分:5)

Here is an answer of mine to a similar question.

基本思想是通用存储库 interfaces 不能很好地工作,但通用存储库实现工作得很好。它使用LINQ to SQL作为示例ORM,并且应该为您的问题提供一些见解。

请务必仔细阅读保罗的回答,尤其是评论。

答案 1 :(得分:1)

这是我见过很多次的问题。您希望将业务对象与数据存储策略分离。当您对业务对象进行投影时,您会失去很多具有存储库的好功能(您可以返回IQueryable,例如使用deffered执行)。您可以实现此目的的唯一方法是为您的存储库提供对IMapper<BusinessObject>的依赖关系。通过这种方式,您可以将业务对象映射到存储库所需的对象,以便存储某些内容,但是当您的业务对象保持持久性无知时,将抽象保留在原位。