为asp.net mvc提供Ninject和Filter属性的dependency injection

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

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

我使用ninject进行dependency injection。 我不想使用工厂或服务定位器模式。

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

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

看到这个答案:

自定义授权MVC 3和Ninject IoC

如果你想使用构造函数注入,那么你需要创build一个属性和一个filter。

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

捆绑:

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

控制器:

 [MyAuthorizeAttribute] public class YourController : Controller { } 

HTH …

强烈推荐BZ的答案。 不要使用[Inject]!

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

BZ的方式也是在维基上,我已经看到许多地方,雷莫尔(Ninject的作者)说,这是正确的方式来做到这一点

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

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

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

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

构造函数注入不能很好地使用属性,因为你将不再能够用它们来装饰控制器/动作。 您只能在NInject中使用带有filter绑定语法的构造函数注入:

 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; } ... } 

接着:

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

BindFilter<>扩展方法在Ninject.Web.Mvc.FilterBindingSyntax命名空间中定义,因此请确保在调用内核之前已将其引入到作用域中。

我发现一个简单的解决scheme,任何Ninject不能处理的场合:

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

其实这正是我用我的自定义AuthorizeAttribute。 比实现一个单独的FilterAttribute容易得多。