3

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

2 回答 2

5

根据我的阅读,将 DataContext用于多个业务对话​​通常是错误的做法。向下滚动到为什么这很重要?报价部分。由于缓存和其他因素,您应该立即考虑您的 DataContext 陈旧。由此可以肯定地说,您不想将 DataContext 保留为所有方法都重用的属性。使用 Eric Duncan 的建议,您将需要传入某种 DataContext 工厂以获取每个查询的新上下文。

对于专注于 DataContext 的讨论,APress Pro LINQ书有一整章介绍了 DataContext,其中最后一页还建议您“立即考虑 DataContext 过时”。

于 2009-03-05T19:16:46.143 回答
3

在 DDD 中,通过引用具体类,您在这里错过了更大的图景。通过最佳实践,您没有在存储库和“服务层”之间进行交互。如果您必须将 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 更改设置等),您将需要使用“工厂”。

工厂看起来像这样:

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

“如何访问 IRepository?” 你可能会问?

您的服务层将执行以下操作:

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,因为它几乎囊括了您的所有需求。

于 2009-03-05T18:58:06.343 回答