Raj*_*Raj 6 dependency-injection inversion-of-control unit-of-work repository-pattern linq-to-sql
似乎有很多关于为Linq to SQL实现Repository模式的例子.其中大部分都是IRepository和DI; 有些人实施了工作单位,有些则没有.我尝试阅读在SO和Google上搜索Linq到SQL存储库模式的大部分结果.尽管如此,我还没有找到完整的解决方案.
从我的阅读中我已经实现了一个存储库模式,如下所示:

我正在使用DI来注册依赖于存储库的接口:
this.container.RegisterType<IConnectionStringFactory, ConnectionStringFactory>(new ContainerControlledLifetimeManager(),
new InjectionConstructor(connectionString));
this.container.RegisterType<IDataContextFactory, DataContextFactory>();
Run Code Online (Sandbox Code Playgroud)
存储库模式的实现:
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)
{
}
}
Run Code Online (Sandbox Code Playgroud)
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);
}
Run Code Online (Sandbox Code Playgroud)
存储库类通过IRepository(未显示)的实现实现如下,并且依赖于DI正在处理的IDataContextFactory:
public class Repository<T> : IRepository<T> where T : class
{
public Repository(IDataContextFactory dataContextFactory)
{
this.dataContextFactory = dataContextFactory;
}
}
Run Code Online (Sandbox Code Playgroud)
使用IoC使用存储库:
PrivilegeRepository repository = container.Resolve<PrivilegeRepository>();
Run Code Online (Sandbox Code Playgroud)
我将查询结果作为Business Object的集合返回,以避免在我使用存储库的应用程序层上依赖Linq to SQL.上面的场景适用于我使用MVVM模式的WPF应用程序.我有ViewModel aks Presenter类,它们不依赖于Linq-SQL生成的类.
如何扩展此模式以便将数据保存到数据库.我想将Business Objects传递回存储库并保存它们.可能吗?如何在这种情况下实施工作单元.
基本思想是通用存储库接口不能很好地工作,但通用存储库实现工作得很好.它使用LINQ to SQL作为示例ORM,并且应该为您的问题提供一些见解.
一定要仔细阅读保罗的回答,特别是评论.
嗯,这是我见过很多次的问题。您希望将业务对象与数据存储策略解耦。当您对业务对象进行投影时,您会失去许多拥有存储库的好功能(例如,您可以使用延迟执行返回 IQueryable)。实现这一点的唯一方法是为您的存储库提供对IMapper<BusinessObject>示例的依赖。通过这种方式,您可以将业务对象映射到存储库所需的对象,以便存储某些内容,但将抽象保留在适当的位置,因为您的业务对象仍然对持久性一无所知。