56 votes

Injection de dépendance avec Ninject et attribut Filter pour asp.net mvc

J'écris un filtre d'autorisation personnalisé pour asp.net mvc 3. Je dois injecter un service utilisateur dans la classe, mais je ne sais pas comment procéder.

 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();
    }
}
 

J'utilise ninject pour l'injection de dépendance. Je ne souhaite pas utiliser un modèle de locataire ou de service.

Mes liaisons ressemblent à ceci dans le fichier global.acsx:

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

82voto

B Z Points 4096

Voir cette réponse:

Autorisation personnalisée MVC 3 et Ninject IoC

Si vous souhaitez utiliser l'injection de constructeur, vous devez créer un attribut et un filtre.

 ///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" } });
          }
      }
}
 

Contraignant:

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

Manette:

 [MyAuthorizeAttribute]
public class YourController : Controller
{

}
 

HTH ...

11voto

John Culviner Points 4878

Je serais très recommandons B Z de la réponse. NE PAS utiliser [Injecter]!

J'ai utilisé un [Injecter] comme Darin Dimitrov a dit était possible et elle a effectivement causé des problèmes de threading sous charge élevée, haute de situations de conflit en conjonction avec .InRequestScope.

B Z s way est aussi ce qui est sur le Wiki, et j'ai vu de nombreux endroits où Remo Gloor (Ninject auteur) dit que c'est la bonne façon de le faire

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

8voto

Darin Dimitrov Points 528142

Sur la façon serait d'utiliser une propriété d'injection et de décorer la propriété avec l' [Inject] d'attribut:

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

    private string[] roles;

    ...
}

Constructeur d'injection ne fonctionne pas bien avec les attributs que vous ne serez plus en mesure de décorer contrôleurs/actions avec eux. Vous ne pourriez utiliser de constructeur d'injection avec le filtre de la syntaxe de liaison dans 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;
    }

    ...
}

et puis:

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

        this.BindFilter<AuthorizeAttribute>(FilterScope.Controller, 0)
            .WhenControllerType<AdminController>();
    }
}

L' BindFilter<> méthode d'extension est définie dans l' Ninject.Web.Mvc.FilterBindingSyntax d'espace de noms, donc assurez-vous que vous avez fait dans le champ d'application avant de l'appeler sur un noyau.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X