2009-06-23 11 views

Odpowiedz

1

Masz dwie opcje

Pierwsza opcja jest napisanie własnego ActionInvoker, która nie jest tak trudne, jak mogłoby się wydawać. Sprawdź to blog post. Dotyczy to w szczególności NInject, ale Unity obsługuje wtrysk własności, więc możesz zmodyfikować przykład użycia Unity.

Jest to opcja, która łączy w pary pojemnik IoC i nie jest zalecana.

public class MyFilter 
{ 
    IMyService MyService {get; set;} 

    MyFilter() : MyFilter(MyUnityContainer.Resolve<IMyService>()) 
    { } 

    MyFilter(IMyService service) 
    { 
    MyService = service; 
    } 
} 
+0

próbowałem znaleźć rozwiązanie w blogu, ale nie wydaje się być pewne różnice między jednością a Ninject, albo gdzieś czyjeś kod jest źle :). Filtry są tylko do odczytu, zanim przejdą do nadpisanego "InvokeExceptionFilters". Więc mogę zadeklarować nowy filtr i wstrzyknąć zależności, ale jeśli spróbuję wstrzyknąć zależności na podanej liście ExceptionFilters, nic się nie dzieje. Mogę utworzyć nowy filtr i przekazać go do klasy bazowej, ale wtedy straciłbym wszystkie deklaratywne informacje podane na samym atrybucie. –

2

Ok, wymyśliłem to.

Głównie użyłem powyższego rozwiązania Bena ze wskazanego przez niego posta na blogu.

Problem polega na tym, że Jedność zachowuje się trochę inaczej.

Nie można wstrzykiwać zależności bezpośrednio z filtrów, ponieważ są one odpowiednio typu IActionFilter i IExceptionFilter. To doprowadziło mnie do przekonania, że ​​są one tylko do odczytu, a tak nie jest. Po prostu Jedność musi znać wyraźny typ, aby wstrzyknąć.

Tak więc, w zastąpionej metody przewidzianej w artykule, użytkownicy Unity muszą zapytać filtry dla typów, o których mowa, a następnie je skompilować.

public UnityActionInvoker(IUnityContainer container, IList<Type> typesToInject) 
     { 
      _container = container; 
      _typesToInject = typesToInject; 
     } 

A potem w zastąpiona metoda, zrobić coś takiego:

var needsInjection = filters.Where(filter => typesToInject.Contains(filter.GetType())); 

Trochę brudny, ale to tylko należy zrobić raz i trzyma wszystko niezwiązanych z wielkością produkcji, jak sugeruje Ben.

Drugim problemem jest to, że nie można wywołać _container.BuildUp (filter) w pętli foreach, ponieważ filtr jest tylko do odczytu w tym kontekście.

1

Ja też natknąłem się na ten problem i mam teraz działające rozwiązanie. Jest podobny do rozwiązania opisanego powyżej, ale z niewielkimi różnicami, a także z dodanym pełnym kodem Unity.

Najpierw użyję wtrysku własności z opisanego powyżej powodu i, jak wyżej, będę używał metody BuildUp na Unity, aby wprowadzić właściwości do już utworzonych filtrów.

Aby to zrobić, wszystkie moje kontrolery dziedziczą z nowej niestandardowej klasy bazowej. W tej klasie bazowej nadpisuję metodę CreateActionInvoker, aby ustawić własny niestandardowy ActionInvoker.

Protected Overrides Function CreateActionInvoker() As System.Web.Mvc.IActionInvoker 
    Return CustomActionInvoker 
End Function 

Następnie w moim CustomActionInvoker przesłonię metodę GetFilters.

Protected Overrides Function GetFilters(ByVal controllerContext As ControllerContext, ByVal actionDescriptor As ActionDescriptor) As FilterInfo 
    Dim info = MyBase.GetFilters(controllerContext, actionDescriptor) 

    For Each MyAuthorizationFilter In info.AuthorizationFilters 
     MvcApplication.Container.BuildUp(MyAuthorizationFilter.GetType, MyAuthorizationFilter) 
    Next 

    For Each MyActionFilter In info.ActionFilters 
     MvcApplication.Container.BuildUp(MyActionFilter.GetType, MyActionFilter) 
    Next 

    For Each MyResultFilter In info.ResultFilters 
     MvcApplication.Container.BuildUp(MyResultFilter.GetType, MyResultFilter) 
    Next 

    For Each MyExceptionFilter In info.ExceptionFilters 
     MvcApplication.Container.BuildUp(MyExceptionFilter.GetType, MyExceptionFilter) 
    Next 

    Return info 
End Function 

Wbrew temu, co wyżej powiedziano, że nie okaże się, że robi to gromadzeniu się wewnątrz pętli For Each spowodowała żadnych problemów.Przezwyciężyłem także pierwotny problem polegający tylko na tym, że obiekt odwoływał się poprzez interfejs, używając jednego z innych przeciążeń metody BuildUp, która pobiera typ System.Type oraz istniejący obiekt.

Po wykonaniu wszystkich powyższych czynności mogę teraz dodawać zależności bezpośrednio do moich filtrów.

Wszelkie komentarze i przemyślenia bardzo doceniane.

Zdrówko Mike

Powiązane problemy