Asp.net-Mvc
如何使用 Ninject 將服務注入授權過濾器?
我正在使用 asp.net mvc 3、ninject 2.0 和 ninject mvc 3 外掛。
我想知道如何將服務層放入我的過濾器(在這種情況下是授權過濾器?)。
我喜歡做建構子注入,所以這是可能的還是我必須注入屬性?
謝謝
編輯
我有這個用於屬性注入,但我的屬性始終為空
[Inject] public IAccountService AccountServiceHelper { get; set; } protected override bool AuthorizeCore(HttpContextBase httpContext) { // check if context is set if (httpContext == null) { throw new ArgumentNullException("httpContext"); } // check if user is authenticated if (httpContext.User.Identity.IsAuthenticated == true) { // stuff here return true; } return false; } /// <summary> /// Application_Start /// </summary> protected void Application_Start() { // Hook our DI stuff when application starts IKernel kernel = SetupDependencyInjection(); RegisterMaps.Register(); AreaRegistration.RegisterAllAreas(); RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes); } public IKernel SetupDependencyInjection() { IKernel kernel = CreateKernel(); // Tell ASP.NET MVC 3 to use our Ninject DI Container DependencyResolver.SetResolver(new NinjectDependencyResolver(kernel)); return kernel; } protected IKernel CreateKernel() { var modules = new INinjectModule[] { new NhibernateModule(), new ServiceModule(), new RepoModule() }; return new StandardKernel(modules); } public class ServiceModule : NinjectModule { public override void Load() { Bind<IAccountService>().To<AccountService>(); } }編輯
我升級到 ninject 2.2 並終於讓它工作了。
編輯 2
我將嘗試為我的授權過濾器執行構造方法,但我不確定如何傳遞角色。我猜我必須通過ninject來做到這一點?
編輯 3
這是我到目前為止所擁有的
public class MyAuthorizeAttribute : AuthorizeAttribute { private readonly IAccountService accountService; public MyAuthorizeAttribute(IAccountService accountService) { this.accountService = accountService; } protected override bool AuthorizeCore(HttpContextBase httpContext) { return base.AuthorizeCore(httpContext); } } this.BindFilter<MyAuthorizeAttribute>(FilterScope.Controller, 0) .WhenControllerHas<MyAuthorizeAttribute>(); [MyAuthorize] public class MyController : BaseController { }它告訴我它想要一個無參數建構子。所以我一定錯過了什麼。
過濾器的問題在於它們是屬性。如果你定義了一個屬性的建構子,它需要一些依賴,你將永遠無法將它應用於任何方法:因為你傳遞給屬性的所有值在編譯時都必須是已知的。
所以基本上你有兩種可能性:
- 使用 Ninject 全域應用過濾器,而不是用它來裝飾你的控制器/動作:
public interface IFoo { } public class Foo : IFoo { } public class MyFooFilter : AuthorizeAttribute { public MyFooFilter(IFoo foo) { } }然後配置核心:
kernel.Bind<IFoo>().To<Foo>(); kernel.BindFilter<MyFooFilter>(FilterScope.Action, 0).When( (controllerContext, actionDescriptor) => string.Equals( controllerContext.RouteData.GetRequiredString("controller"), "home", StringComparison.OrdinalIgnoreCase ) );
- 使用屬性注入:
public interface IFoo { } public class Foo : IFoo { } public class MyFooFilter : AuthorizeAttribute { [Inject] public IFoo Foo { get; set; } }然後配置核心:
kernel.Bind<IFoo>().To<Foo>();並用您的自定義過濾器裝飾一些控制器/動作:
[MyFooFilter] public ActionResult Index() { return View(); }