将datacontext设置为属性是否存在任何潜在问题:
存储库
public Repository()
{
public DataContext dc {get;set;}
public GetOrders(int id)
{ ...from dc.Orders...}
}
服务层:
public GetNewOrders()
{
....
Repository rep=new Repository();
using {DataContext dc=new DataContext())
{
rep.dc=dc;
rep.GetOrders(id);
}
}
答案 0 :(得分:5)
根据我的阅读,使用DataContext“for more than one business conversation is usually the wrong thing to do”。向下滚动到为什么这么重要?部分的报价。由于缓存和其他因素,您应该立即考虑您的DataContext陈旧。由此可以肯定地说,您不希望将DataContext保留为所有方法都重用的属性。使用Eric Duncan的建议,您将需要传递某种DataContext工厂来为每个查询获取新的上下文。
对于专注于DataContext的讨论,APress Pro LINQ 本书在DataContext上有一个entire chapter,其very last page也建议你“考虑DataContext马上过时了。“
答案 1 :(得分:3)
在DDD中,你通过引用concret类错过了这里的大局。您不是通过最佳实践在存储库和“服务层”之间进行交互。如果必须将DataContext注入到存储库中,我建议重构为:
public interface IRepository
{
IList<Orders> GetNewOrders();
}
public Repository : IRepository
{
private IDataContext _dataContext;
public Repository(IDataContext dataContext)
{
_dataContext = dataContext;
}
public IList<Orders> GetNewOrders()
{
// perform your actions on _dataContext here
}
}
更好的解决方案是让Repository自己处理DataContext - 通过屏蔽底层需求来保持Concert的分离:
public interface IRepository
{
IList<Orders> GetNewOrders();
}
public Repository : IRepository
{
private IDataContext _dataContext;
public Repository(String connectionString)
{
_dataContext = new DataContext(connectionString);
}
public IList<Orders> GetNewOrders()
{
// perform your actions on _dataContext here
}
}
如果您必须自己保持对DataContext(或其他类)的控制(可能您希望保留静态引用,或者更改基于WebRequest的设置等),则需要使用“Factory”。
工厂看起来像这样:
public static class DataContextFactory
{
public static IDataContext GetInstance()
{
// return either a static instance,
// or threaded instance, a GlobalContext instance
// or whatever your preference is here
//
}
}
这样,您就可以完全控制DataContext实例在外部和远离“服务”层的控制方式。因此,您将使用此DataContextFactory,如下所示:
public interface IRepository
{
IList<Orders> GetNewOrders();
}
public Repository : IRepository
{
public IList<Orders> GetNewOrders()
{
using (var dataContext = DataContextFactory.GetInstance())
{
// dataContext is now your IDataContext to work with
}
}
}
您的服务层可以执行以下操作:
public void GetNewOrdersForServices()
{
// Not recommended!
// IRepository repo = new Repository()
//
// The following is recommended instead; because, it removes the
// the Concret reference from your Services layer completely!
//
IRepository repo = ServiceLocator.InstanceOf<IRepository>();
IList myList = repo.GetNewOrders();
}
或者,您可以使用您最喜欢的Inversion of Control容器将其注入服务的构造函数中,如下所示:
public class OrderService
{
private IRepository _repo;
public OrderService(IRepository repo)
{
_repo = repo;
}
public void GetNewOrdersForServices()
{
IList myList = _repo.GetNewOrders();
}
如果您与服务定位器概念不相似,请查看Castle Windsor,因为它封装了您的所有需求。