Asp.net-Mvc

如何使用 Ninject 將服務注入授權過濾器?

  • June 17, 2011

我正在使用 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
   {
}

它告訴我它想要一個無參數建構子。所以我一定錯過了什麼。

過濾器的問題在於它們是屬性。如果你定義了一個屬性的建構子,它需要一些依賴,你將永遠無法將它應用於任何方法:因為你傳遞給屬性的所有值在編譯時都必須是已知的。

所以基本上你有兩種可能性:

  1. 使用 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
       )
);
  1. 使用屬性注入:
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();
}

引用自:https://stackoverflow.com/questions/6364047