问题
I am using asp.net mvc 3, ninject 2.0 and the ninject mvc 3 plugin.
I am wondering how do I get service layers into my filter(in this case an authorization filter?).
I like to do constructor inject so is this possible or do I have to property inject?
Thanks
Edit
I have this for property inject but my property is always null
[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>();
}
}
Edit
I upgraded to ninject 2.2 and get finally got it work.
Edit 2
I am going to try and do the constructor way for my authorize filter but I am unsure how to pass in the Roles. I am guessing I have to do it through ninject?
Edit 3
This is what I have so far
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
{
}
It tells me it want's a no parameter constructor. So I must be missing something.
回答1:
The problem with filters is that they are attributes. And if you define a constructor of an attribute that expects some dependency you will never gonna be able to apply it to any method: because all values that you pass to attributes must be known at compile time.
So basically you have two possibilities:
Use Ninject to apply the filter globally instead of decorating your controllers/actions with it:
public interface IFoo { } public class Foo : IFoo { } public class MyFooFilter : AuthorizeAttribute { public MyFooFilter(IFoo foo) { } }
and then configure the kernel:
kernel.Bind<IFoo>().To<Foo>(); kernel.BindFilter<MyFooFilter>(FilterScope.Action, 0).When( (controllerContext, actionDescriptor) => string.Equals( controllerContext.RouteData.GetRequiredString("controller"), "home", StringComparison.OrdinalIgnoreCase ) );
Use property injection:
public interface IFoo { } public class Foo : IFoo { } public class MyFooFilter : AuthorizeAttribute { [Inject] public IFoo Foo { get; set; } }
and then configure the kernel:
kernel.Bind<IFoo>().To<Foo>();
and decorate some controller/action with your custom filter:
[MyFooFilter] public ActionResult Index() { return View(); }
回答2:
See this question /answer here:
Setup filter attribute for dependency injection to accept params in constructor
and here
Dependency Injection with Ninject and Filter attribute for asp.net mvc
来源:https://stackoverflow.com/questions/6364047/how-to-use-ninject-to-inject-services-into-an-authorization-filter