2012-04-11 13 views
6

Mam filtr akcji w aplikacji ASP.NET MVC 3, która wymaga wstrzyknięcia pewnych zależności. Używam Autofac.Mvc3 jako wtryskiwacza zależności.Autofac nie wypełnia właściwości filtra akcji

Po prostu muszę zarejestrować typy, które chcę wstrzyknąć, zadzwonić pod numer RegisterFilterProvider i umieścić właściwość publiczną na moim filtrze akcji, a następnie autofac wypełni właściwość odpowiednim obiektem podczas instancji filtra.

Tutaj jest częścią mojego działania filtra:

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 

Tutaj jest częścią mojego 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 

Włożyłem breakpoint prawo po SetResolver w bezpośrednim oknie próbował :

DependencyResolver.Current.GetService(Of TraceSource) 

I udało mi się uzyskać obiekt TraceSource z autofac, więc rejestracja wydaje się być OK.

Ale podczas OnActionExecuting mój tracer nieruchomość jest pusta.

Czego mi brakowało?

Odpowiedz

4

IIRC dostawca nie działa z filtrami "globalnymi".

usunąć tę funkcję:

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

I zamiast, zarejestruj globalne filtry z Autofac bezpośrednio:

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

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

Autofac stworzy filtry i uwzględnić je w odpowiedni sposób. Zaletą tego podejścia jest to, że można go refaktoryzować, aby filtry nie były pochodnymi atrybutów, a następnie użyć konstruktora zamiast wtrysku własności.

+0

Dzięki! Na razie po prostu bezpośrednio nazywam 'DependencyResolver.Current.GetService (Of TraceSource)' w filtrze, ale spróbuję twoją sugestię później. –

+2

Odpowiedź powyżej w C#: 'builder.Register (c => new MyHandleErrorAttribute()) \t \t \t \t .AsExceptionFilterFor () .InstancePerHttpRequest();' – Pete

+0

aw przypadku, gdy nie jest to filtr działanie błędu rejestracja będzie wyglądać tak: builder.Register (c => new SomeGlobalActionFilter()) .AsActionFilterFor () .PropertiesAutowired(). InstancePerRequest(); – Sergey

Powiązane problemy