Ninject и MVC3: внедрение зависимостей в фильтры действий
Я нашел множество неубедительных статей и вопросов о том, как сделать внедрение свойства в ActionFilter в ASP.NET MVC3 с использованием Ninject.
Может ли кто-нибудь дать мне четкий пример, пожалуйста?
Вот мой пользовательский атрибут аутентификации.
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
[Inject]
public IService Service { get; set; }
[Inject]
public IAuthenticationHelper AuthenticationHelper { get; set; }
public override void OnAuthorization(AuthorizationContext filterContext)
{
//My custom code
}
}
Я использую WebActivator для настройки Ninject
[assembly: WebActivator.PreApplicationStartMethod(typeof(MyProject.Web.AppStart_NinjectMvc3), "Start")]
namespace MyProject.Web {
public static class AppStart_NinjectMvc3 {
public static void RegisterServices(IKernel kernel) {
//Binding things
}
public static void Start() {
// Create Ninject DI Kernel
IKernel kernel = new StandardKernel();
// Register services with our Ninject DI Container
RegisterServices(kernel);
// Tell ASP.NET MVC 3 to use our Ninject DI Container
DependencyResolver.SetResolver(new NinjectServiceLocator(kernel));
}
}
}
Мой сервис и помощник никогда не вводятся. Что мне нужно изменить?
2 ответа
Вот как вы могли бы продолжить:
public class MvcApplication : Ninject.Web.Mvc.NinjectHttpApplication
{
private class MyModule : NinjectModule
{
public override void Load()
{
Bind<IService>().To<ServiceImpl>();
Bind<IAuthenticationHelper>().To<AuthenticationHelperImpl>();
}
}
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
protected override void OnApplicationStarted()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
protected override IKernel CreateKernel()
{
var modules = new INinjectModule[] {
new MyModule()
};
var kernel = new StandardKernel(modules);
DependencyResolver.SetResolver(new NinjectDependencyResolver(kernel));
return kernel;
}
}
и тогда вы можете иметь свой собственный атрибут авторизации:
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
[Inject]
public IService Service { get; set; }
[Inject]
public IAuthenticationHelper AuthenticationHelper { get; set; }
public override void OnAuthorization(AuthorizationContext filterContext)
{
}
}
и действие контроллера, украшенное этим:
[CustomAuthorize]
public ActionResult Index()
{
return View();
}
и зависимости должны быть введены.
На мой взгляд, есть лучшее решение, чем использование атрибутов фильтра. Посмотрите мои посты об альтернативном способе объявления фильтров с помощью Ninject. Он не требует внедрения свойства и использует вместо этого конструктор:
http://www.planetgeek.ch/2010/11/13/official-ninject-mvc-extension-gets-support-for-mvc3/ http://www.planetgeek.ch/2011/02/22/ninject-mvc3-and-ninject-web-mvc3-merged-to-one-package/