2015-10-19 3 views
3

по умолчанию MVC 5 + Идентичность 2.1 Проект содержит следующую строку (в Startup.Auth.cs):Почему это ОК не Утилизировать в UserStore

app.CreatePerOwinContext<ApplicationUserManager>ApplicationUserManager.Create); 

... где определен статический метод Create (в IdentityConfig.cs) следующим образом:

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

Я думаю, что это нормально, потому что UserStore фактически обертывает класс Entity Framework DbContext. И хотя DbContext также является Disposable, но refer to this blog post распоряжение DbContext не является обязательным. Также стоит отметить, что удаление инъекционного объекта не является хорошей идеей, ведь ответственность за управление жизненным циклом объекта лежит на инжекторе. Поэтому, очевидно, UserManager доза не утилизируется UserStore в этом случае.

+0

Вы читали комментарии к этому сообщению? Они излагают некоторые очень веские причины для вызова Dispose в контексте, хотя это не является строго необходимым. –

+0

Я никоим образом не предполагал, что 'ApplicationUserManager' * должен * нести ответственность за удаление контекста - это не то поведение, которое я хотел бы видеть. Однако в структуре есть классы, которые ведут себя так. –

+0

Конечно, размещение одноразового объекта - хорошая идея. Я попытался сказать, что в этом случае утилизация 'DbContext' не нужна, и вы можете ее опустить. Как и в этом примере. Кстати, если вы действительно хотите избавиться от «UserStore», просто поместите его в контекст «Owin» и получите его в методе «Создать». Диспетчер контекста Owin будет распоряжаться им. –

1

Немного поздно, но я создаю проект MVC 5 и могу подтвердить, что Dispose в UserStore вызывается каждый раз, когда HTTP-запрос завершен.

Я считаю, что он исходит из ссылки IOwinContext при создании ApplicationUserManager. В частности, контекст используется для получения DbContext:

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

В классе запуска объект IAppBuilder сконфигурирован для CreatePerOwinContext:

app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create); 

Если переопределить метод UserStore Dispose:

protected override void Dispose(bool disposing) 
    { 
     base.Dispose(disposing); 
    } 

После выполнения base.Dispose (распоряжение) свойство Context UserStore становится null.

 Смежные вопросы

  • Нет связанных вопросов^_^