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