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

Linq to sql 使用IoC的Linq到SQL的存储库模式、依赖项注入、工作单元,linq-to-sql,dependency-injection,inversion-of-control,repository-pattern,unit-of-work,Linq To Sql,Dependency Injection,Inversion Of Control,Repository Pattern,Unit Of Work,似乎有很多关于为Linq到SQL实现存储库模式的例子。它们大多具有易位性和DI性;有些实施了工作单元,有些没有。我试图阅读SO和Google在LINQtoSQL存储库模式上搜索返回的大部分结果。尽管如此,我还没有找到一个完整的解决方案 根据我的阅读资料,我实现了一个存储库模式,如下所示: 资料来源: 我使用DI注册存储库所依赖的接口: this.container.RegisterType<IConnectionStringFactory, ConnectionStringFactory

似乎有很多关于为Linq到SQL实现存储库模式的例子。它们大多具有易位性和DI性;有些实施了工作单元,有些没有。我试图阅读SO和Google在LINQtoSQL存储库模式上搜索返回的大部分结果。尽管如此,我还没有找到一个完整的解决方案

根据我的阅读资料,我实现了一个存储库模式,如下所示:

资料来源:

我使用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>();
我将查询结果作为业务对象的集合返回,以避免在使用存储库的应用程序层上依赖Linq to SQL。上述场景适用于使用MVVM模式的WPF应用程序。我有ViewModel aks Presenter类,它们不依赖于Linq SQL生成的类


如何扩展此模式,以便将数据保存到数据库中。我希望将业务对象传递回存储库并保存它们。可能吗?在这种情况下,我如何实现工作单元。

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

基本思想是,通用存储库接口工作得不太好,但通用存储库实现工作得很好。它使用LINQtoSQL作为示例ORM,应该可以为您的问题提供一些见解


一定要通读Paul的答案,尤其是评论。

你可能想看看活动记录模式;它涵盖了完整的CRUD操作以及类似于存储库的查询访问功能。VS2010附带的实体框架呢?@Raj我想你错过了他想要独立于ORM的事实。