I have an action filter in an ASP.NET MVC 3 app that needs some dependencies injected into it. I am using Autofac.Mvc3 as the dependency injector.
According to the autofac wiki I just have to register the types that I want to inject, call RegisterFilterProvider, and put a public property on my action filter, and then autofac will fill the property with the right object during filter instantiation.
Here is a part of my action filter:
Public Class LogActionAttribute
    Inherits ActionFilterAttribute
    Property tracer As TraceSource
    Public Overrides Sub OnActionExecuting(filterContext As System.Web.Mvc.ActionExecutingContext)
        ...
        tracer.TraceData(...)
        ...
    End Sub
End Class
Here is a part of my global.asax:
Public Class MvcApplication
    Inherits System.Web.HttpApplication
    Shared Sub RegisterGlobalFilters(ByVal filters As GlobalFilterCollection)
        filters.Add(New MyHandleErrorAttribute)
        filters.Add(New LogActionAttribute)
    End Sub
    Sub Application_Start()
        InitSettingRepoEtc()
        ...
    End Sub
    Protected Shared Sub InitSettingRepoEtc()
        ...
        Dim builder = New ContainerBuilder
        builder.RegisterControllers(Reflection.Assembly.GetExecutingAssembly)
        ...
        builder.Register(Of TraceSource)(
            Function(x) New TraceSource("requests", SourceLevels.All)).InstancePerHttpRequest()
        ...
        builder.RegisterFilterProvider()
        Dim container = builder.Build
        DependencyResolver.SetResolver(New AutofacDependencyResolver(container))
        ...
    End Sub
End Class
I have put breakpoint right after SetResolver and in the immediate window tried:
DependencyResolver.Current.GetService(Of TraceSource)
And I successfully got a TraceSource object from autofac, so the registration seems to be OK.
But during OnActionExecuting my tracer property is empty.
What did I miss?
IIRC the provider doesn't work with 'global' filters.
Remove this function:
Shared Sub RegisterGlobalFilters(ByVal filters As GlobalFilterCollection)
    filters.Add(New MyHandleErrorAttribute)
    filters.Add(New LogActionAttribute)
End Sub
And instead, register the global filters with Autofac directly:
 builder.Register(Of MyHandleErrorAttribute)
     .As(Of IActionFilter)
     .PropertiesAutowired()
     .SingleInstance();
 builder.Register(Of LogActionAttribute)
     .As(Of IActionFilter)
     .PropertiesAutowired()
     .SingleInstance();
Autofac will create the filters and include them appropriately. The advantage of this approach is that you can refactor so the filters are not attribute-derived, and then use constructor rather than property injection.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With