Внедрение зависимостей с помощью Ninject и глобального фильтра: IAuthorizationFilter

Я использую стандартный загрузчик NinjectMVC3, установленный в папке App_Start.

Мой класс приложения выглядит так:

public class MvcApplication : HttpApplication
{
    static void RegisterRoutes(RouteCollection routes)
    {
        // ... routes here ...
    }

    public void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);
    }

    static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        // empty
    }
}

У меня есть только следующие правила торгов, зарегистрированные в NinjectMVC3:

Bind<IAccountsRepository>().To<AccountsRepository>();
this.BindFilter<GlobalAuthFilter>(FilterScope.Global, 0);

И мой глобальный фильтр:

public class GlobalAuthFilter : IAuthorizationFilter
{
    readonly IAccountsRepository _accountsRepository;

    public GlobalAuthFilter(IAccountsRepository accountsRepository)
    {
        _accountsRepository = accountsRepository;
    }

    public void OnAuthorization(AuthorizationContext context)
    {
        // Code here never reached. Why? What's wrong?
    }
}

В моем приложении есть какие-то контроллеры. И я хочу вызывать OnAuthorization для каждого вызова действия для каждого контроллера.

Но мой код не работает. Спасибо.


person Jean Louis    schedule 31.01.2012    source источник


Ответы (1)


Из вашего кода не совсем понятно, где конкретно вы настраиваете свое ядро. Это нужно сделать в методе RegisterServices метода ~/App_Start/NinjectMVC3.cs:

/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
    kernel.Bind<IAccountsRepository>().To<AccountsRepository>();
    kernel.BindFilter<GlobalAuthFilter>(FilterScope.Global, 0);
}        

Когда вы устанавливаете пакет Ninject.MVC3 NuGet, тело этого метода будет пустым, и именно здесь вы должны либо напрямую настроить зависимости, либо определить модули Ninject, которые вы бы импортировали в этом методе:

/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
    kernel.Load(new MyModule());
}        

где вы определили пользовательский модуль:

public class MyModule : NinjectModule
{
    public override void Load()
    {
        this.Bind<IAccountsRepository>().To<AccountsRepository>();
        this.BindFilter<GlobalAuthFilter>(FilterScope.Global, 0);
    }
}
person Darin Dimitrov    schedule 31.01.2012
comment
Да, я поместил правила привязки в RegisterServices. Но это не работает. - person Jean Louis; 31.01.2012
comment
@JeanLouis, я только что протестировал этот код, и он работал отлично. Шаги: 1. Создайте новое приложение ASP.NET MVC 3. 2. Установите NuGet-пакет Ninject.MVC3. 3. Определите типы IAccountsRepository, AccountsRepository и GlobalAuthFilter. 4. Поместите код, который я показал в своем ответе, в методе RegisterServices. 5. Запустите приложение. 6. Выполняется OnAuthorization. - person Darin Dimitrov; 31.01.2012
comment
Я обновил свой ответ, чтобы проиллюстрировать пример с модулями Ninject. - person Darin Dimitrov; 31.01.2012
comment
Да, ты прав. Значит у меня другая ошибка. Спасибо за вашу помощь. - person Jean Louis; 31.01.2012
comment
Не забывайте, что BindFilter<T>() — это метод расширения, расположенный в Ninject.Web.Mvc.FilterBindingSyntax. - person solidau; 02.07.2013
comment
Не плохо ли зарегистрировать глобальные фильтры в конфигурации ninject вместо использования FilterConfig? - person Mutex; 01.04.2015