为什么可以不处理UserStore的Dispose方法?

4
默认的MVC 5 + Identity 2.1 项目包含这条语句(在 Startup.Auth.cs 文件中):
app.CreatePerOwinContext<ApplicationUserManager>ApplicationUserManager.Create);

在IdentityConfig.cs中定义了静态Create方法,如下所示:

public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context) 
{
    var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
     ...
}

请看这段代码,注意新的UserStore<ApplicationUser>是如何创建并传入ApplicationUserManager构造函数中的。还要注意UserStore<T>是可处理的(基类实现了IDisposable)。
这让我感到奇怪,因为我想知道谁负责处理那个新创建的UserStore。我预计ApplicationUserManager(或其基类)在其自身被处理时必须对其进行处理。但是没有:我查看了源代码,似乎并没有这样做。所以没有人处理那个实例!
这为什么可以呢?在什么情况下你会想处理实现IDisposable的类的实例?
2个回答

2

我认为这是可以的,因为UserStore实际上是包装了Entity Framework的DbContext类。而DbContext也是Disposable,但是参考这篇博客文章可以知道,处理DbContext并不是强制性的。此外,值得指出的是,在注入对象时处理它们并不是一个好主意,事实上,管理对象的生命周期是注入器的职责。因此,在这种情况下,显然UserManager不会处理UserStore


你看过那篇文章的评论了吗?它们列举了一些非常好的理由,即使不是绝对必要的情况下也应该调用上下文的Dispose方法。 - Gary McGill
我绝不是在暗示 ApplicationUserManager 应该负责处理上下文的释放 - 那不是我想看到的行为。然而,框架中有一些类的行为就是这样的。 - Gary McGill
当然,处理可处理对象是个好主意。我试图说,在这种情况下,处理 DbContext 不是必要的,你可以省略它。就像他们在这个例子中所做的那样。顺便说一句,如果你真的想处理 UserStore,只需将其放入 Owin 上下文中,并在 Create 方法中检索它。Owin 上下文管理器会处理它。 - Sam FarajpourGhamari

1

虽然有点晚,但我一直在创建一个MVC5项目,并确认每次http请求完成时都会调用UserStore的Dispose方法。

我认为这源自于创建ApplicationUserManager时使用的IOwinContext引用。具体来说,是使用的上下文来获取DbContext:

new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>())

在 Startup 类中,IAppBuilder 对象被配置为 CreatePerOwinContext:
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);

如果您覆盖了UserStore的Dispose方法:
protected override void Dispose(bool disposing)
    {
        base.Dispose(disposing);
    }

在执行base.Dispose(disposing)之后,UserStore的Context属性变为null。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接