E 'possibile utilizzare Dependency Injection / IOC su ASP.NET MVC FilterAttribute?
Domanda
Ho una semplice FilterAttribute
personalizzato che uso decorare vari ActionMethods
.
ad es.
[AcceptVerbs(HttpVerbs.Get)]
[MyCustomFilter]
public ActionResult Bar(...)
{ ... }
Ora, desidero aggiungere un po 'di registrazione a questa azione CustomFilter .. quindi essere un bravo ragazzo, sto usando DI/IoC
... e come tale desidera utilizzare questo modello per il mio FilterAttribute
personalizzato.
Quindi, se ho il seguente ...
ILoggingService
e desiderio di aggiungere questo mio FilterAttribute
personalizzato .. io non sono sicuro di come. Come, è facile per me fare il seguente ...
public class MyCustomFilterAttribute : FilterAttribute
{
public MyCustomFilterAttribute(ILoggingService loggingService)
{ ... }
}
Ma gli errori del compilatore dicendo l'attributo che decora la mia ActionMethod
(elencate sopra ...) richiede 1 arg .. quindi io sono solo che non so cosa fare: (
Soluzione
devo iniezione proprietà lavorare con Ninject e la Ninject.Web.MVC .
Fino a quando hai la fabbrica di controller dal Ninject.Web.MVC, è piuttosto semplice.
per es.
public class EventExistsAttribute : FilterAttribute, IActionFilter
{
[Inject]
public IEventRepository EventRepo { private get; set; }
public void OnActionExecuting(ActionExecutingContext filterContext)
{
//Do stuff
}
public void OnActionExecuted(ActionExecutedContext filterContext)
{
//Do something else if you so wish...
}
}
Si ha l'inconveniente di avere una dipendenza essenzialmente 'nascosto', per così dire ... ma non c'è molto che si può fare al riguardo.
HTHS,
Charles
Altri suggerimenti
È necessario scrivere il proprio IActionInvoker e fare l'iniezione di proprietà. Date un'occhiata a questo post da Jimmy Bogard per le idee.
Sì, è possibile utilizzare l'iniezione di dipendenza su un FilterAttribute. Tuttavia non è possibile utilizzare l'iniezione costruttore su una FilterAttribute. Questa non è una limitazione di ASP.NET MVC, è comune a tutto il codice Net, come i valori passati in un attributi constuctor sono limitati a tipi semplici .
[MyFilter(ILogger logger)] // this will not compile
public ActionResult Index()
{
return View();
}
Quindi, la pratica comune è quello di rendere la dipendenza di un proprietà del vostro filtro, come l'esempio di @ Charlino. È quindi possibile utilizzare l'iniezione di proprietà. È possibile utilizzare Ninject per decorare la proprietà filtro come in @ esempio di Charlino. O come suggerito da @mrydengren, si può fare questo in una sottoclasse personalizzata di ControllerActionInvoker.