使用IoC、依赖注入和工作单元的Linq to SQL仓储模式

7
有很多关于实现Linq to SQL仓储模式的例子。其中大部分都涉及到IRepository和DI;一些实现了工作单元,而有些没有。我尝试阅读了SO和Google上关于Linq to SQL仓储模式的搜索结果。然而,我还没有找到完整的解决方案。
根据我的阅读,我已经实现了以下仓储模式: repository pattern (来源:baburajpb at sites.google.com
我使用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的实现(未显示),并且依赖于IDataContextFactory,由DI负责处理:

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和Presenter类,它们不依赖于由Linq-SQL生成的类。
如何扩展此模式以便将数据保存到数据库?我想将业务对象传回存储库并将其保存。是否可能?在这种情况下如何实现工作单元?

你可能想要查看Active Record模式;它涵盖了完整的CRUD操作以及类似于仓储的查询访问能力。 - Cylon Cat
VS2010内置的Entity Framework怎么样? - Raj
@Raj,我觉得你忽略了他想要ORM独立的事实。 - Novus
2个回答

5

这是我对类似问题的回答。

基本思路是通用仓库接口不太好用,但通用仓库实现非常好用。它以LINQ to SQL作为示例ORM,应该对您的问题提供一些见解。

一定要仔细阅读Paul的答案,特别是评论部分。


1

这是一个我经常遇到的问题。您希望将业务对象与数据存储策略解耦。当您对业务对象进行投影时,会失去许多拥有存储库的好处(例如,您可以返回IQueryable并利用延迟执行)。您唯一能够实现此目标的方法是向您的存储库提供依赖于IMapper<BusinessObject>的接口。通过这种方式,您可以将业务对象映射到存储库需要的对象,同时保持抽象,因为您的业务对象仍然保持持久性无知。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接