UnityFilterAttributeFilterProvider Not Working

Apr 23, 2014 at 1:13 PM
Edited Apr 23, 2014 at 1:24 PM
Hi, I've installed the Unity.Mvc NuGet package but I can't seem to inject dependencies into attributes. For example I have the following global attribute:
public class ConfigAttribute : ActionFilterAttribute {
    [Dependency]
    public ISomeService SomeService { get; set; }

    public override void OnActionExecuting(ActionExecutingContext filterContext) {
        var data = SomeService.GetData();

        base.OnActionExecuting(filterContext);
    }
}
Which I have added like so (within the Application_Start event):
GlobalFilters.Filters.Add(new ConfigAttribute());
However SomeService is null. I'd appreciate it if someone could show me what i'm doing wrong.

Thanks
Apr 24, 2014 at 1:13 AM
Edited Apr 24, 2014 at 1:14 AM
If you are using straight ASP.NET MVC you shouldn't have anything to do. You don't need to register any filter attributes (e.g GlobalFilters.Filters.Add(new ConfigAttribute());) since Unity provides UnityFilterAttributeFilterProvider which should be setup when you install Unity bootstrapper for ASP.NET MVC and performs a BuildUp injecting dependencies..

If you are using ASP.NET Web API then see http://unity.codeplex.com/discussions/446780 for a similar discussion.

Here are the steps I did to get it working for ASP.NET MVC:

  1. Install Unity bootstrapper for ASP.NET MVC from NuGet
  2. Create ConfigAttribute class
  3. Create ISomeService and SomeService
  4. In UnityConfig.RegisterTypes register SomeService: container.RegisterType<ISomeService, SomeService>();
  5. Apply ConfigAttribute to a Controller
After that the Filter is invoked and the dependency is injected.

If there are still issues then flesh out the sample code or upload a sample solution to help pinpoint the issue.

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Apr 24, 2014 at 7:54 AM
Hi thanks for your reply. I followed along with your steps until point 5. I wish to add my filter globally instead of having to manually add the filter as an attribute to a controller. That's what I figured the GlobalFilters collection did?
Apr 24, 2014 at 8:05 AM
OK, I see. The reason why there is no injection for ConfigAttribute is that it is being instantiated directly. If you resolve ConfigAttribute from Unity or use the DependencyResolver then the dependency will be injected. See this thread for a very similar question: http://entlib.codeplex.com/discussions/472066 .

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Apr 24, 2014 at 10:01 AM
Edited Apr 24, 2014 at 10:32 AM
Thanks I managed to come up with another hacky solution. However I ran into another issue since the dependencies were stored against the lifetime of the filter. I therefore came up with a less than idea solution. See:

http://stackoverflow.com/questions/23249365/nhibernate-session-closed-in-global-action-filter

Would your proposed fix of resolving the dependencies when you register the filter run into similar issues?
Apr 28, 2014 at 7:02 AM
If you are going to register a singleton instance as a global filter the dependencies injected will only be injected once and not change per request.

Using a service locator (as in your example) can help with this or alternatively using a factory (if you don't like service locators). If you register ISession using a PerRequestLifetimeManager then each request should get separate instance of ISession. I'm not familiar with nHibernate so I worry/wonder if ISession is somehow automatically scoped to the current session (which I assume will be related to the current executing web request).

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Marked as answer by nfplee on 4/29/2014 at 6:02 AM
Apr 29, 2014 at 1:01 PM
Thanks, I think I'll leave it as is for now until I find some more time to do load testing.