У меня есть приложение .NET MVC 5 .NET Framework, которое я конвертирую в .NET Core 2.1
У меня есть фильтр настраиваемых действий, который в версии .NET Framework был зарегистрирован как глобальный фильтр в Filterconfigкласс как показано ниже:
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new MyCustomActionFilter());
}
}
В фильтре настраиваемых действий в версии .NET я использовал шаблон локатора службы (я знаю, что это можно рассматривать как шаблон), как показано ниже:
var myService = DependencyResolver.Current.GetService<IMyService>();
Я использую Simple Injector для DI, и все отлично работает в версии .NET.В версии .NET Core я пытаюсь заставить работать ту же функциональность, но myService всегда имеет значение null
Я все еще использую Simple Injector (так как все другие проекты в решении используют его, и они не переходят кПроекты .NET Core (только веб).
Мой класс Startup.cs имеет следующий код:
services.Configure<MvcOptions>(options =>
{
options.Filters.Add(new MyCustomActionFilter());
});
SimpleInjectorConfig.IntegrateSimpleInjector(services, container);
На моем уровне обслуживания у меня есть класс SimpleInjector Registartion, который вызывается изВеб-слой - затем вызывается до уровня DAL для регистрации
public class SimpleInjectorRegistration
{
public static void RegisterServices(Container container)
{
container.Register<IMyService, MyService>();
//further code removed for brevity
Когда я запускаю приложение с точкой останова в пользовательском фильтре и точкой останова в этом методе RegisterServices, я вижу точку останова в методе RegisterServicesСначала получают удар, а затем точку останова в пользовательском фильтре - это заставляет меня думать, что все было правильно подключено в контейнере.
Однако я пытаюсь сделать следующее снова в пользовательском фильтре с .NET Core Service Locatorpattern
var myService = filterContext.HttpContext.RequestServices.GetService<IMyService>();
но результат всегда нулевой?
Есть ли такЧто я пропустил в этой настройке?
------------ ОБНОВЛЕНИЕ -------------------
На основе комментария Стивенса я добавил конструктор в свой фильтр действий и передал в контейнер Simple Injector.
Итак, класс My Startup теперь имеет вид:
public class Startup
{
//Simple Injector container
private Container container = new Container();
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
services.Configure<MvcOptions>(options =>
{
options.Filters.Add(new MyCustomActionFilter(container));
Мой пользовательский фильтр теперь похож на приведенный ниже конструктор:
public class MyCustomActionFilter : ActionFilterAttribute
{
private readonly IMyService _myService;
public MyCustomActionFilter(Container container)
{
_myService = container.GetService<IMyService>();
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
//actual code of custom filter removed - use of MyService
Я установил точку останова на конструкторе MyCustomActionFilter, и я вижу, что он получает удар, но я получаю ошибку:
SimpleInjector.ActivationException: 'IDbContext зарегистрирован как образ жизни с асинхронной областью действия, но экземпляр запрашивается вне контекста активной области (асинхронной области).'
MyService имеет зависимость отDbContext, который вводится в него (он выполняет работу, сохраняя и извлекая данные из БД.
Для контекста БД я зарегистрировал его следующим образом:
public class SimpleInjectorRegistration
{
public static void RegisterServices(Container container, string connectionString)
{
container.Register<IDbContext>(() => new MyDbContext(connectionString),
Lifestyle.Scoped);
}
}