UnitOfWork в фильтре действий, похоже, кеширует - PullRequest
12 голосов
/ 17 марта 2011

У меня есть сайт MVC 3, который использует IoC (Unity), и моя модель генерируется с EF4 и POCO. Я использую фильтр действий для фиксации моего UnitOfWork:

public class UseUnitOfWorkAttribute : ActionFilterAttribute, IActionFilter
{
    private readonly IUnitOfWork _unitOfWork;

    public UseUnitOfWorkAttribute()
    {
        _unitOfWork = IoCFactory.Instance.CurrentContainer.Resolve<IUnitOfWork>();
    }

    void IActionFilter.OnActionExecuted(ActionExecutedContext filterContext)
    {
        _unitOfWork.Commit();
    }

    void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext)
    {
    }
}

Однако, несмотря на то, что Commit(), похоже, запускается, он как-то кеширует то, что считает "грязным".

Например, в моем контроллере из класса обслуживания выполняется следующее:

var user = _userRepository.Single(u => u.Id == 2);
user.DateAdded = DateTime.Now;

Всякий раз, когда я делаю свежую сборку решения и нажимаю на это действие контроллера, изменение фактически фиксируется. Однако последовательные попадания в контроллер ничего не делают.

С другой стороны, если я помещаю UnitOfWork в свой контроллер и фиксирую его после вызова метода сервиса, он работает как положено (каждый раз, когда я запрашиваю действие контроллера):

public AccountController()
{
    _unitOfWork = IoCFactory.Instance.CurrentContainer.Resolve<IUnitOfWork>();
}

public ActionResult Test()
{
    var user = _userRepository.Single(u => u.Id == 2);
    user.DateAdded = DateTime.Now;
    _unitOfWork.Commit();
}

Так что определенно кажется, что происходит какое-то кэширование, но я не могу понять, что кэшируется - UnitOfWork, ActionFilter или репозиторий.

Есть идеи, что может происходить? А если нет, какие-нибудь идеи, что еще я мог бы сделать, чтобы устранить неполадки?

Заранее спасибо.

Ответы [ 3 ]

27 голосов
/ 17 марта 2011

Вы инициализируете свою единицу работы в конструкторе фильтра действий, что означает, что она будет внедрена при создании экземпляра фильтра действий.Цитата из примечаний к выпуску ASP.NET MVC 3 :

В предыдущих версиях ASP.NET MVC фильтры действий создавались для запроса, за исключением нескольких случаев.Такое поведение никогда не было гарантированным поведением, а являлось лишь деталью реализации, и контракт на фильтры заключался в том, чтобы считать их не имеющими состояния.В ASP.NET MVC 3 фильтры кэшируются более агрессивно.Поэтому любые фильтры пользовательских действий, которые неправильно хранят состояние экземпляра, могут быть повреждены.

6 голосов
/ 17 марта 2011

Убедитесь, что контейнер зависимостей возвращает один и тот же экземпляр во всех местах и ​​перепишите фильтр, чтобы избежать кэширования состояния:

public class UseUnitOfWorkAttribute : ActionFilterAttribute, IActionFilter
{
    void IActionFilter.OnActionExecuted(ActionExecutedContext filterContext)
    {
        var unitOfWork = IoCFactory.Instance.CurrentContainer.Resolve<IUnitOfWork>();
        unitOfWork.Commit();
    }

    void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext)
    {
    }
}
0 голосов
/ 17 марта 2011

Я бы проверил время жизни в вашем хранилище. Это, безусловно, было причиной нашей реализации.

...