Utilisation de Unity pour injecter des dépendances dans un ActionFilter personnalisé

Pour le moment, j’ai une ControllerFactory personnalisée dans laquelle j’injecte mon conteneur Unity:

dans global.asax Application_Start ():

var container = InitContainer(); DependencyResolver.SetResolver(new UnityDependencyResolver(container)); var factory = new UnityControllerFactory(container); ControllerBuilder.Current.SetControllerFactory(factory); 

Dans la fabrique de contrôleurs, j’ai configuré mes contrôleurs pour utiliser un ActionInvoker personnalisé comme suit:

 protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType) { var controller = base.GetControllerInstance(requestContext, controllerType) as Controller; if (controller != null) controller.ActionInvoker = new UnityActionInvoker(_container); return controller; } 

Enfin, dans mon ActionInvoker personnalisé, j’essaie de créer des actions appelées à l’aide du conteneur ActionInvokers:

 protected override ActionExecutedContext InvokeActionMethodWithFilters( ControllerContext controllerContext, IList filters, ActionDescriptor actionDescriptor, IDictionary parameters) { var builtUpFilters = new List(); foreach (IActionFilter actionFilter in filters) { builtUpFilters.Add(_container.BuildUp(actionFilter)); } return base.InvokeActionMethodWithFilters(controllerContext, builtUpFilters, actionDescriptor, parameters); } 

Voici un exemple de l’un des ActionFilters en cours de construction:

 public class PopulatRolesAtsortingbute : ActionFilterAtsortingbute, IActionFilter { private const ssortingng RolesKey = "roles"; [Dependency] public Func Service { get; set; } public PopulatRolesAtsortingbute() { } public override void OnActionExecuting(ActionExecutingContext filterContext) { if (filterContext.Controller.ViewData[RolesKey] == null) { filterContext.Controller.ViewData[RolesKey] = Service().GetRoles(); } } } 

Le problème est que la propriété publique de mon ActionFilterAtsortingbute personnalisé n’est jamais injectée, elle rest nulle lors de l’exécution! Je ne vois pas pourquoi mon filtre n’est pas correctement construit par le conteneur. Le type injecté est correctement enregistré, comme suit:

 container.RegisterInstance(new ChannelFactory( new BasicHttpBinding(), new EndpointAddress("http://example.com/ABSApplication/MetadataService.svc"))); container.RegisterInstance<Func>( () => container.Resolve<ChannelFactory>().CreateChannel()); 

Et est également injecté ailleurs dans l’application (Bien que pas via .Buildup). C’est à peu près le même processus suivi par cet article de blog . Quelle pièce du puzzle me manque?

Je le ferais légèrement différemment. Je voudrais:

  1. installez le paquet de nuget unity.mvc3

  2. appelez la méthode bootstrapped.initialise () comme indiqué dans la documentation txt que le package ajoute au projet

  3. définir votre mappage IMetadataService dans l’initialisation à votre type Concrete

  4. append IMetadataService à votre constructeur

La différence entre votre implémentation et l’article que vous avez mentionné est que vous utilisez Func, ce qui ne dit rien si cela ajoute un problème différent au mixage présenté ici. Je dois imaginer que c’est comme la méthode ci-dessus (sans Func) fonctionne bien pour moi.

Edit: le code de Brad Wilson a bien fonctionné pour moi ici: http://bradwilson.typepad.com/blog/2010/07/service-location-pt4-filters.html

Pièces applicables (s’il vous plaît voir le lien ci-dessus)

Global.asax.cs

protected void Application_Start() { // ... var oldProvider = FilterProviders.Providers.Single( f => f is FilterAtsortingbuteFilterProvider ); FilterProviders.Providers.Remove(oldProvider); var container = new UnityContainer(); var provider = new UnityFilterAtsortingbuteFilterProvider(container); FilterProviders.Providers.Add(provider); // ... }
protected void Application_Start() { // ... var oldProvider = FilterProviders.Providers.Single( f => f is FilterAtsortingbuteFilterProvider ); FilterProviders.Providers.Remove(oldProvider); var container = new UnityContainer(); var provider = new UnityFilterAtsortingbuteFilterProvider(container); FilterProviders.Providers.Add(provider); // ... } 

Le filtre lui-même:

using System; using System.Web.Mvc; using Microsoft.Practices.Unity; public class InjectedFilterAtsortingbute : ActionFilterAtsortingbute { [Dependency] public IMathService MathService { get; set; } public override void OnResultExecuted(ResultExecutedContext filterContext) { filterContext.HttpContext.Response.Write( Ssortingng.Format(" 

Le filtre indique que 2 + 3 est {0}.

", MathService.Add (2, 3)) ) } }

et UnityFilterAtsortingbuteFilterProvider.cs

using System.Collections.Generic; using System.Web.Mvc; using Microsoft.Practices.Unity; public class UnityFilterAtsortingbuteFilterProvider : FilterAtsortingbuteFilterProvider { private IUnityContainer _container; public UnityFilterAtsortingbuteFilterProvider(IUnityContainer container) { _container = container; } protected override IEnumerable GetControllerAtsortingbutes( ControllerContext controllerContext, ActionDescriptor actionDescriptor) { var atsortingbutes = base.GetControllerAtsortingbutes(controllerContext, actionDescriptor); foreach (var atsortingbute in atsortingbutes) { _container.BuildUp(atsortingbute.GetType(), atsortingbute); } return atsortingbutes; } protected override IEnumerable GetActionAtsortingbutes( ControllerContext controllerContext, ActionDescriptor actionDescriptor) { var atsortingbutes = base.GetActionAtsortingbutes(controllerContext, actionDescriptor); foreach (var atsortingbute in atsortingbutes) { _container.BuildUp(atsortingbute.GetType(), atsortingbute); } return atsortingbutes; } }
using System.Collections.Generic; using System.Web.Mvc; using Microsoft.Practices.Unity; public class UnityFilterAtsortingbuteFilterProvider : FilterAtsortingbuteFilterProvider { private IUnityContainer _container; public UnityFilterAtsortingbuteFilterProvider(IUnityContainer container) { _container = container; } protected override IEnumerable GetControllerAtsortingbutes( ControllerContext controllerContext, ActionDescriptor actionDescriptor) { var atsortingbutes = base.GetControllerAtsortingbutes(controllerContext, actionDescriptor); foreach (var atsortingbute in atsortingbutes) { _container.BuildUp(atsortingbute.GetType(), atsortingbute); } return atsortingbutes; } protected override IEnumerable GetActionAtsortingbutes( ControllerContext controllerContext, ActionDescriptor actionDescriptor) { var atsortingbutes = base.GetActionAtsortingbutes(controllerContext, actionDescriptor); foreach (var atsortingbute in atsortingbutes) { _container.BuildUp(atsortingbute.GetType(), atsortingbute); } return atsortingbutes; } }