Инъекция зависимостей для ASP.NET WebAPI ActionFilters с использованием Ninject не работает
Я пытаюсь настроить DI на ActionFilters в ASP.NET WebAPI, используя Ninject. Я выполнил следующие инструкции: https://github.com/ninject/Ninject.Web.WebApi/wiki/Dependency-injection-for-filters
Я создаю свой ActionFilter следующим образом:
public class ApiAuthorizeFilter : AbstractActionFilter
{
private readonly IValidateApiTokenService _validateApiTokenService;
public ApiAuthorizeFilter(IValidateApiTokenService validateApiTokenService)
{
_validateApiTokenService = validateApiTokenService;
}
public override bool AllowMultiple => true;
public override void OnActionExecuting(HttpActionContext actionContext)
{
}
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
}
}
Я сконфигурирован так:
kernel.BindHttpFilter<ApiAuthorizeFilter>(FilterScope.Controller);
Мое понимание, основанное на информации по вышеуказанной ссылке, заключается в том, что ActionFilter должен запускаться для всех действий во всех контроллерах WebAPI. Тем не менее, я установил точки останова как при переопределенных методах в фильтре, так и в них никогда не попадает. Я установил точку останова в конфигурации и могу подтвердить, что она выполняется.
Что мне не хватает? Мне нужен этот ActionFilter для запуска всех действий в каждом ApiController в моем проекте.
Ответы
Ответ 1
в вашем классе запуска
public void Configuration(IAppBuilder app)
{
var kernel = new StandardKernel();
// register IValidateApiTokenService
var config = new HttpConfiguration();
config.Filters.Add(new ApiAuthorizeFilter(kernel.Get<IValidateApiTokenService>());
}
Ответ 2
Причина, по которой это не работает, заключается в том, что ActionFilters (или любые фильтры, если на то пошло) создаются в виде одиночек по времени выполнения (один раз навсегда в контексте приложения), и вообще любой контейнер DI имеет проблемы с подключением объектные переходные и/или одноразовые зависимости, если этот объект является одиночным.
Одним из решений вашей проблемы будет использование встроенного локатора сервисов, например:
DependencyResolver.Current.GetService(typeof(IValidateApiTokenService));
Я лично не использую Ninject для своих потребностей DI, но если выше это не работает, возможно, потребуется некоторое подключение к началу DI или использовать интеграционный пакет, подобный этому:
https://github.com/ninject/ninject.web.mvc/wiki/MVC3
Ответ 3
Я никогда не работал над Ninject, я работал над Unity. Имея опыт работы с Unity, я попытаюсь пролить свет на проблему.
Я не уверен, в чем цель _validateApiTokenService
, но то, что я могу наблюдать из вышеприведенного кода, заключается в том, что вам нужно настроить привязку зависимости к реализации IValidateApiTokenService
. Наряду со следующим кодом
kernel.BindHttpFilter<ApiAuthorizeFilter>(FilterScope.Controller);
возможно, вам нужно что-то вроде
kernel.Bind<IValidateApiTokenService>().To<ValidateApiTokenService>();
или
kernel.Bind<IValidateApiTokenService>.To<ValidateApiTokenService>().InSingletonScope();
если он находится в области Singleton.