在数据访问层访问 HttpContext.Current

发布于 2024-10-10 07:07:37 字数 729 浏览 5 评论 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 变量。我不确定这是否是一个好的做法,想知道您的意见。

Based on the given answer to my question at Entity Framework in layered architecture, Now I'd like to move my repositories (Which are now only responsible for CRUD abstraction, not business logic stuff) to DAL and reserve BLL for Business Logic.
I've come to the conclusion that the entity context should be considered a unit-of-work and therefore not reused. So I'd like to create an obejctcontext per HttpContext in my repositories to prevent performance/thread [un]safety issues. I'd like to define the objectcontext in repositories as follows:

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

In that case, the DAL project should be aware of HttpContext.Current variable. I'm not sure if this is a good practice and would like to know your opinions.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

偏爱自由 2024-10-17 07:07:37

不访问 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 容器构建整个对象层次结构。

对于控制容器的反转,请检查例如 温莎城堡。我正在使用 MS Unity,但它不提供开箱即用的每个 HTTP 生命周期管理器。

No accessing HttpContext outside of the web application is bad practice because it tightly couples your code to web environment. What you are looking for is probably inversion of control container with per HTTP request object lifetime manager.

Suppose that you define your business logic as:

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

  ...
}

Now when you want to use BusinessService you have to create its instance and pass it IObjectContext as parameter. When using inversion of control container you can take advantage of this definition and instead of constructor call something like:

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

Inversion of control (IoC) container has to be configured to be able to instantiate concrete implementation of IBusinessService and IObjectContext. Moreover this configuration usually allows defining lifetime of instantiated object. When per HTTP lifetime is allowed each call to Resolve within single request returns same instance.

You can go even futher by letting container resolve the class using your business services. It is usually done with ASP.NET MVC. In such case you only define constructors receiving services as parameters in your main classes (controllers) and let IoC container to build whole object hiearchy.

For inversion of control containers check for example Windsor Castle. I'm using MS Unity but it doesn't provide per HTTP lifetime manager out of the box.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文