Autofac не заполняет свойство фильтра действий

У меня есть фильтр действий в приложении ASP.NET MVC 3, которому нужно ввести некоторые зависимости. Я использую Autofac.Mvc3 в качестве инжектора зависимостей.

Согласно вики autofac, мне просто нужно зарегистрировать типы, которые я хочу внедрить, вызовите RegisterFilterProvider , и поместите общедоступное свойство в мой фильтр действий, а затем autofac заполнит свойство правильным объектом во время создания экземпляра фильтра.

Вот часть моего фильтра действий:

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

Вот часть моего 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

Я поставил точку останова сразу после SetResolver и в ближайшем окне попробовал:

DependencyResolver.Current.GetService(Of TraceSource)

И я успешно получил объект TraceSource от autofac, так что с регистрацией все в порядке.

Но во время OnActionExecuting моя собственность tracer пуста.

Что я пропустил?


person Endy Tjahjono    schedule 11.04.2012    source источник


Ответы (1)


IIRC поставщик не работает с «глобальными» фильтрами.

Удалите эту функцию:

Shared Sub RegisterGlobalFilters(ByVal filters As GlobalFilterCollection)
    filters.Add(New MyHandleErrorAttribute)
    filters.Add(New LogActionAttribute)
End Sub

Вместо этого зарегистрируйте глобальные фильтры непосредственно в Autofac:

 builder.Register(Of MyHandleErrorAttribute)
     .As(Of IActionFilter)
     .PropertiesAutowired()
     .SingleInstance();

 builder.Register(Of LogActionAttribute)
     .As(Of IActionFilter)
     .PropertiesAutowired()
     .SingleInstance();

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

person Nicholas Blumhardt    schedule 11.04.2012
comment
Спасибо! Пока я просто вызываю DependencyResolver.Current.GetService(Of TraceSource) в фильтре напрямую, но я попробую ваше предложение позже. - person Endy Tjahjono; 13.04.2012
comment
Ответ выше на С#: builder.Register(c => new MyHandleErrorAttribute()) .AsExceptionFilterFor<Controller>().InstancePerHttpRequest(); - person Pete; 03.02.2014
comment
а в случае, если это не фильтр действий при ошибке, регистрация будет выглядеть так: builder.Register(c => new SomeGlobalActionFilter()) .AsActionFilterFor‹Controller›().PropertiesAutowired().InstancePerRequest(); - person Sergey; 07.01.2015