0

基于对我在分层架构中的实体框架中的问题给出的答案,现在我想将我的存储库(现在只负责 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 变量。我不确定这是否是一个好的做法,并想知道您的意见。

4

1 回答 1

2

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

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

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

  ...
}

现在,当您想使用 BusinessService 时,您必须创建它的实例并将 IObjectContext 作为参数传递给它。当使用控制容器的反转时,您可以利用这个定义,而不是构造函数调用类似的东西:

IBusinessService service = container.Resolve<IBusinessService>();

控制反转 (IoC) 容器必须配置为能够实例化 IBusinessService 和 IObjectContext 的具体实现。此外,这种配置通常允许定义实例化对象的生命周期。当允许每个 HTTP 生命周期时,在单个请求中对 Resolve 的每次调用都会返回相同的实例。

通过让容器使用您的业务服务解析类,您可以走得更远。它通常使用ASP.NET MVC完成。在这种情况下,您只需将接收服务的构造函数定义为主类(控制器)中的参数,并让 IoC 容器构建整个对象层次结构。

对于控制容器的反转检查,例如Windsor Castle。我正在使用 MS Unity,但它没有提供开箱即用的每个 HTTP 生命周期管理器。

于 2011-01-06T09:57:42.300 回答