Я боролся с этим некоторое время и наконец решил свою проблему.Итак, вот мое решение в надежде, что оно может помочь кому-то еще.
Настройка: 1. У меня есть проект MVC3, фильтр настраиваемых действий, который обращается к БД с помощью EF5 через бизнес-сервис.2. Я использую Unity и unity.MVC, чтобы разрешить свои зависимости для каждого запроса.3. Я использую внедрение свойств в свой пользовательский фильтр действий, так как он имеет конструктор без параметров.
Результат.Внедрение зависимостей работает корректно для всех сервисов, используемых действиями, мой EF DbContext корректно удаляется в конце каждого запроса.
Проблема Несмотря на то, что моя зависимость свойства решена в моем фильтре настраиваемых действий, он содержит устаревшиеэкземпляр моего DbContext (например, он, кажется, был кэширован из предыдущего запроса)
Как упоминалось в предыдущих статьях, MVC3 более агрессивен в отношении кэширования фильтра, и на состояние фильтра нельзя полагаться.Поэтому было предложено разрешить зависимость в методе OnActionExecuting.Таким образом, я удалил свое введенное свойство и сделал то, что назвало решимость, в моем контейнере единства.Однако я все еще получил устаревшую версию DbContext.Любые изменения в БД были правильно запрошены в моих основных действиях, но фильтр пользовательских действий не принимал их.
Решение.Unity.MVC Управляет временем жизни каждого запроса, используя дочерние контейнеры и удаляя их в конце каждого запроса.Разрешая мои зависимости в фильтре действий из моего контейнера Unity, я разрешал из родительского контейнера, который не удаляется при каждом запросе.
Поэтому вместо
IoC.Instance.CurrentContainer.Resolve<IService>();
я использовал это дляполучите экземпляр дочернего контейнера, а не родительского.
var childContainer = HttpContext.Current.Items["perRequestContainer"] as IUnityContainer;
var service = childContainer.Resolve<IServcie>();
Я уверен, что должен быть чистый способ добиться того же результата, поэтому, пожалуйста, добавьте предложения.
Хорошо, небольшое уточнениечтобы мой модульный тест позволил внедрить макет сервиса.1. удалите разрешение зависимостей из OnActionexecuting и добавьте два конструктора.
public MyCustomActionfilter() : this(((IUnityContainer)HttpContext.Current.Items["perRequestContainer"].Resolve<IService>())
и
public MyCustomActionfilter(IService service)
{
this.service = service;
}
Теперь конструктор разрешает вашу службу и сохраняет ее как частную только для чтения.Теперь это можно использовать в функции OnActionExecutng.Модульные тесты теперь могут вызывать второй конструктор и вводить макет.