asp.net mvc的Ninject和Filter属性的依赖注入

Sha*_*ean 56 asp.net-mvc ninject asp.net-mvc-3

我正在为asp.net mvc 3编写自定义授权过滤器.我需要向用户服务注入类,但我不知道如何做到这一点.

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

我正在使用ninject进行依赖注入.我不想使用Factory或服务定位器模式.

我的绑定在global.acsx中看起来像这样:

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

B Z*_*B Z 81

看到这个答案:

自定义授权MVC 3和Ninject IoC

如果要使用构造函数注入,则需要创建属性和过滤器.

///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" } });
          }
      }
}
Run Code Online (Sandbox Code Playgroud)

捆绑:

this.BindFilter<MyAuthorizeFilter>(System.Web.Mvc.FilterScope.Controller, 0).WhenControllerHas<MyAuthorizeAttribute>();
Run Code Online (Sandbox Code Playgroud)

控制器:

[MyAuthorizeAttribute]
public class YourController : Controller
{

}
Run Code Online (Sandbox Code Playgroud)

HTH ...

  • 你将如何设置实现以适应:`[MyAuthorizeAttribute("Admin","Contributer")]`?传递参数. (6认同)
  • https://github.com/ninject/ninject.web.mvc/wiki/Filter-configurations +1给出支持构造函数而不是属性注入的答案 (4认同)

Joh*_*ner 11

强烈推荐BZ的回答.不要使用[注入]!

我使用像Darin Dimitrov这样的[Inject]说可能并且它实际上在高负载,高争用情况下与.InRequestScope一起引起了线程问题.

BZ的方式也是Wiki上的内容,我看过很多地方,Remo Gloor(Ninject作者)说这是正确的做法

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

Downvote [注入]答案在这里,因为严重的你会被烧毁(如果你之前没有正确加载测试,可能在生产中!)


Wol*_*ang 9

我找到了一个简单的解决方案,适用于Ninject不处理施工的任何场合:

var session = (IMyUserService)DependencyResolver.Current.GetService(typeof (IMyUserService));
Run Code Online (Sandbox Code Playgroud)

实际上这正是我使用自定义AuthorizeAttribute的原因.比实现单独的FilterAttribute容易得多.


Dar*_*rov 8

在途中将使用属性注入并使用属性装饰[Inject]属性:

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

    private string[] roles;

    ...
}
Run Code Online (Sandbox Code Playgroud)

构造函数注入对属性不起作用,因为您将无法再使用它们来装饰控制器/操作.您只能在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;
    }

    ...
}
Run Code Online (Sandbox Code Playgroud)

然后:

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

        this.BindFilter<AuthorizeAttribute>(FilterScope.Controller, 0)
            .WhenControllerType<AdminController>();
    }
}
Run Code Online (Sandbox Code Playgroud)

BindFilter<>扩展方法在定义Ninject.Web.Mvc.FilterBindingSyntax空间中,因此请确保您已经带来了进入范围调用它在内核前.

  • 我强烈推荐BZ的回答.不要使用[Inject]它可以在高负荷下创造竞赛条件! (2认同)