asp.net-mvc asp.net-mvc-3 ninject

Inyección de dependencia con el atributo Ninject y filtro para asp.net mvc



asp.net-mvc asp.net-mvc-3 (4)

En el camino sería usar una inyección de propiedad y decorar la propiedad con el atributo [Inject] :

public class AuthorizeAttribute : FilterAttribute, IAuthorizationFilter { [Inject] public IUserService UserService { get; set; } private string[] roles; ... }

La inyección de Constructor no funciona bien con los atributos, ya que ya no podrá adornar los controladores / acciones con ellos. Solo se podía usar la inyección de constructor con la sintaxis de enlace de filtro en NInject:

public class AuthorizeAttribute : FilterAttribute, IAuthorizationFilter { private readonly IUserService userService; private string[] roles; public AuthorizeAttribute(IUserService userService, params string[] roles) { this.userService = userService; this.roles = roles; } ... }

y entonces:

internal class SiteModule : Ninject.Modules.NinjectModule { public override void Load() { Bind<IUserService>().To<UserService>(); this.BindFilter<AuthorizeAttribute>(FilterScope.Controller, 0) .WhenControllerType<AdminController>(); } }

El método de extensión BindFilter<> se define en el espacio de nombres Ninject.Web.Mvc.FilterBindingSyntax así que asegúrese de haberlo incluido en el alcance antes de llamarlo a un kernel.

Estoy escribiendo un filtro de autorización personalizado para asp.net mvc 3. Necesito inyectar un servicio de usuario en la clase, pero no tengo idea de cómo hacerlo.

public class AuthorizeAttribute : FilterAttribute, IAuthorizationFilter { private IUserService userService; private string[] roles; public AuthorizeAttribute(params string[] roles) { this.roles = roles; } public void OnAuthorization(AuthorizationContext filterContext) { throw new NotImplementedException(); } }

Estoy usando ninject para inyección de dependencia. No quiero utilizar un patrón de localizador de fábrica o de servicio.

Mis enlaces se ven así en global.acsx:

internal class SiteModule : NinjectModule { public override void Load() { Bind<IUserService>().To<UserService>(); } }


Encontré una solución simple para cualquier ocasión donde Ninject no maneja la construcción:

var session = (IMyUserService)DependencyResolver.Current.GetService(typeof (IMyUserService));

En realidad, esto es exactamente lo que estoy usando con mi AuthorizeAttribute personalizado. Mucho más fácil que tener que implementar un FilterAttribute separado.


Recomiendo encarecidamente la respuesta de BZ. NO use [Inyectar]!

Usé un [Inyectar] como Darin Dimitrov dijo que era posible y que en realidad causó problemas de subprocesos en situaciones de alta carga y alta contención junto con .InRequestScope.

El camino de BZ también está en la Wiki y he visto muchos lugares donde Remo Gloor (autor de Ninject) dice que esta es la forma correcta de hacerlo

github.com/ninject/ninject.web.mvc/wiki/Filter-configurations

Downvote [Inyectar] respuestas aquí porque en serio te quemarás (¡probablemente en producción si no cargas la prueba correctamente antes!)


Ver esta respuesta:

Autorización personalizada MVC 3 y Ninject IoC

Si desea utilizar la inyección de constructor, debe crear un atributo y un filtro.

///marker attribute public class MyAuthorizeAttribute : FilterAttribute { } //filter public class MyAuthorizeFilter : IAuthorizationFilter { private readonly IUserService _userService; public MyAuthorizeFilter(IUserService userService) { _userService = userService; } public void OnAuthorization(AuthorizationContext filterContext) { var validUser = _userService.CheckIsValid(); if (!validUser) { filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary { { "action", "AccessDenied" }, { "controller", "Error" } }); } } }

Unión:

this.BindFilter<MyAuthorizeFilter>(System.Web.Mvc.FilterScope.Controller, 0).WhenControllerHas<MyAuthorizeAttribute>();

Controlador:

[MyAuthorizeAttribute] public class YourController : Controller { }

HTH ...