Unity,使用Statement和PerRequestLifetimeManager

时间:2014-06-03 07:07:25

标签: c# entity-framework asp.net-mvc-4 unity-container

我在我的项目中使用Unity。但我不确定我是否应该使用using声明,因为我正在使用PerRequestLifetimeManager

简单示例:

注射:

container.RegisterType<IDataContext, MyContext>(new PerRequestLifetimeManager());

用法:

class MyClass
{
     private readonly IDataContext _context;

     public MyClass(IDataContext context)
     {
           _context = context;
     }

     public string MyMethod()
     {
          // 1. Is this needed?
          using (var u = _context)
          {
               var customers = u.Set<Customer>().OrderBy(o => o.Name);
               // ........
          }

          // 2. OR can I just do this
          var customers = _context.Set<Customer>().OrderBy(o => o.Name);

由于我在注射中使用PerRequestLifetimeManager(),这是否会否定using语句的要求,因为上下文将在每个http请求之后被处理掉?

2 个答案:

答案 0 :(得分:2)

如果您将使用,那么您将立即处置DbContext,如果您再次尝试访问它将导致异常,因此1方法通常是坏主意。 2会工作,但如果在DbContext中会出现问题,例如你想要保留的新数据将不符合db设计(例如索引)。在这种情况下,您将无法重新创建DbContext。我的建议是注册然后解决DbContexts的工厂方法:

class MyClass
{
     private readonly Func<IDataContext> _contextFactory;

     public MyClass(Func<IDataContext> contextFactory)
     {
           _contextFactory = contextFactory;
     }

     public string MyMethod()
     {
           // 1. Is this needed?
           using (var u = _contextFactory())
           { 
               var customers = u.Set<Customer>().OrderBy(o => o.Name);
               // ........
           }
     }

答案 1 :(得分:1)

在使用MVC4时使用工作单元和存储库模式的最佳做法。在每次创建上下文时,最好在App_Start文件夹的UnityConfig.cs文件中注册上下文。如

container.RegisterType<IDataContext, MyContext>(new PerRequestLifetimeManager());

在此之后,当您启动应用程序时,上下文将处于打开状态,直到您的应用程序关闭。所以,不要在使用上下文时使用using语句。它将在完成using后处理您的上下文,并且上下文将无法进一步提供,并且在关闭using后使用上下文时,您必须得到例如上下文不可用的异常。所以,只需使用

var customers = _context.Set<Customer>().OrderBy(o => o.Name);