Architecture 在数据访问层访问HttpContext.Current

Architecture 在数据访问层访问HttpContext.Current,architecture,entity-framework-4,repository,httpcontext,objectcontext,Architecture,Entity Framework 4,Repository,Httpcontext,Objectcontext,根据对我的问题的给定答案,现在我想将我的存储库(现在只负责CRUD抽象,而不负责业务逻辑的东西)移动到DAL并为业务逻辑保留BLL。 我得出的结论是,实体上下文应该被视为一个工作单元,因此不能重用。因此,我想在我的存储库中为每个HttpContext创建一个obejctcontext,以防止性能/线程[un]安全问题。我想在存储库中定义objectcontext,如下所示: public MyDBEntities ctx { get {

根据对我的问题的给定答案,现在我想将我的存储库(现在只负责CRUD抽象,而不负责业务逻辑的东西)移动到DAL并为业务逻辑保留BLL。
我得出的结论是,实体上下文应该被视为一个工作单元,因此不能重用。因此,我想在我的存储库中为每个HttpContext创建一个obejctcontext,以防止性能/线程[un]安全问题。我想在存储库中定义objectcontext,如下所示:

public MyDBEntities ctx
    {
        get
        {
            string ocKey = "ctx_" + HttpContext.Current.GetHashCode().ToString("x");
            if (!HttpContext.Current.Items.Contains(ocKey))
                HttpContext.Current.Items.Add(ocKey, new MyDBEntities ());
            return HttpContext.Current.Items[ocKey] as MyDBEntities ;
        }
    }

在这种情况下,DAL项目应该知道HttpContext.Current变量。我不确定这是否是一种好的做法,我想知道您的意见。

在web应用程序之外不访问HttpContext是一种不好的做法,因为它将您的代码与web环境紧密地结合在一起。您正在寻找的可能是使用每HTTP请求对象生命周期管理器反转控制容器

假设您将业务逻辑定义为:

public class BusinessService : IBusinessService
{ 
  // Constructor with dependency injection
  public BusinessService(IObjectContext context)
  { ... }

  ...
}
现在,当您想要使用BusinessService时,必须创建其实例并将其作为参数传递给IObjectContext。使用控制容器反转时,您可以利用此定义,而不是构造函数调用如下内容:

IBusinessService service = container.Resolve<IBusinessService>();
IBusinessService=container.Resolve();
必须配置控制反转(IoC)容器,以便能够实例化IBusinessService和IObjectContext的具体实现。此外,这种配置通常允许定义实例化对象的生存期。当允许每个HTTP生存期时,在单个请求中解析的每个调用都返回相同的实例

通过让容器使用您的业务服务解析类,您可以更进一步。这通常是用铅笔做的。在这种情况下,您只将接收服务的构造函数定义为主类(控制器)中的参数,并让IoC容器构建整个对象层次结构


例如,对于控制容器的反转检查。我使用的是MS Unity,但它没有为每个HTTP lifetime manager提供现成的功能。

+1回答得好。我使用StructureMap管理每个Http请求的OC。它有现成的HTTP生命周期管理。谢谢你的回答。我不熟悉国际奥委会的概念。你有关于我应该如何实现它的一些真实示例的来源吗?实际上,你发现了一些有趣的东西。Autofac似乎很有前途。