2009-06-23 9 views

Antwort

1

Sie haben zwei Möglichkeiten

Die erste Option ist eine benutzerdefinierte ActionInvoker zu schreiben, die so hart nicht annähernd wie es klingt. Überprüfen Sie diese blog post. Es befasst sich speziell mit NInject, aber Unity unterstützt die Injektion von Eigenschaften, sodass Sie das Beispiel für die Verwendung von Unity ändern können.

Dies ist die Option, die Ihren IoC-Container koppelt und nicht empfohlen wird.

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

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

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

ich versuchte, die Lösung in dem Blog-Eintrag gefunden, aber es scheint einige Unterschiede zwischen Unity und Ninject zu sein, oder sonst irgendwo, jemand Code falsch :) ist. Die Filter werden nur gelesen, wenn sie zum überschriebenen "InvokeExceptionFilters" gelangen. So kann ich einen neuen Filter deklarieren und Abhängigkeiten injizieren, aber wenn ich versuche, Abhängigkeiten auf die angegebene Liste von Exceptionfilters zu injizieren, passiert nichts. Ich könnte einen neuen Filter erstellen und es an die Basisklasse übergeben, aber dann würde ich alle deklarativen Informationen verlieren, die für das Attribut selbst bereitgestellt werden. –

2

Ok, fand es heraus.

Meistens nutzte ich Bens Lösung oben aus dem Blogbeitrag, auf den er zeigte.

Das Problem ist, dass Unity ein wenig anders verhält.

Sie können keine Abhängigkeiten direkt von den Filtern importieren, da sie vom Typ IActionFilter bzw. IExceptionFilter sind. Dies führte mich zu der Annahme, dass sie nur gelesen wurden, was nicht so ist. Es ist nur, dass Unity den expliziten Typ kennen muss, um injizieren zu können.

In der vom Artikel bereitgestellten überschriebenen Methode müssen Unity-Benutzer daher die Filter für die fraglichen Typen abfragen und sie dann aufbauen.

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

Und dann in der überschriebenen Methode, etwas tun, wie folgt aus:

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

Ein bisschen chaotisch, aber es muss nur einmal durchgeführt werden, und hält alles entkoppelt wie Ben schlägt.

Das andere Problem ist, dass Sie _container.BuildUp (Filter) nicht innerhalb einer foreach-Schleife aufrufen können, da der Filter in diesem Kontext schreibgeschützt ist.

1

Ich bin auch auf dieses Problem gestoßen und habe jetzt eine funktionierende Lösung. Es ist ähnlich der oben beschriebenen Lösung, aber mit einigen kleinen Unterschieden und auch mit dem vollständigen Unity-Code.

Zuerst werde ich Property-Injection aus dem oben beschriebenen Grund verwenden, und wie oben werde ich die BuildUp-Methode auf Unity verwenden, um die Eigenschaften in die bereits erstellten Filter zu injizieren.

Dazu habe ich alle meine Controller erben von einer neuen benutzerdefinierten Basisklasse. In dieser Basisklasse überschreibe ich die CreateActionInvoker-Methode, um meinen eigenen benutzerdefinierten ActionInvoker festzulegen.

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

Dann überschreibe ich in meinem CustomActionInvoker die GetFilters-Methode.

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 

Im Gegensatz zu dem, was gesagt wird oben habe ich nicht feststellen, dass Probleme verursacht For Each-Schleife innerhalb eines um den Aufbau zu tun.Ich habe auch das ursprüngliche Problem überwunden, dass das Objekt nur über eine Schnittstelle referenziert wird, indem eine der anderen Überladungen der BuildUp-Methode verwendet wird, die sowohl einen System.Type als auch das vorhandene Objekt verwendet.

Mit all den oben getan, was ich jetzt Abhängigkeiten direkt in meine Filter injizieren kann.

Alle Kommentare und Gedanken sehr geschätzt.

Prost Mike

Verwandte Themen