Question

I have the following global action filter:

public class AddWidgetsAttribute : ActionFilterAttribute {
    private ISession _session;
    public ISession Session {
        get {
            if (_session == null)
                _session = DependencyResolver.Current.GetService<ISession>();
            return _session;
        }
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext) {
        filterContext.Controller.ViewBag.Widgets = Session.Query<Widget>().ToList();
    }
}

Here's the code which adds the filter in the Application_Start event:

GlobalFilters.Filters.Add(new AddWidgetsAttribute());

This works fine on the first request but then it throws an error telling me the session is closed. If I change the Session property to the following:

public ISession Session {
    get { return DependencyResolver.Current.GetService<ISession>(); }
}

It works fine but it seems like abit of a hack. Is there a nice way to inject the dependency within global action filters?

I'd appreciate the help. Thanks

Was it helpful?

Solution

There is no problem doing this, but, keep in your mind, if you instance a global filter, it will add a single instance into your application. So, your code check if the _session object is not null and instance it, but, when you close the session you still have the reference on the global filter, because it is a single instance, and worst, the session is closed. So, the next access will get a non null object and closed session.

I would keep the DependencyResolver to give me the instance of the session everytime, because you are controlling it in another level (I want to understand you are doing a session per request).

public ISession Session 
{
   get 
   {
      return DependencyResolver.Current.GetService<ISession>();
   }
}

And the asp.net mvc will get the right instance every request.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top