2016-11-19 2 views
2
  • Я использую ASP.NET Сердечник
  • Мой IService зарегистрирован контейнер DI
  • Есть две реализации: FooService и BarService
  • Я должен выбрать услугу, основанную на MVC зоне текущего запроса в

Так что мне нужно что-то вроде:Определение ASP.NET MVC сердечника Область при регистрации службы

services.AddScoped<IService>(
    c => IsThisTheFooArea 
     ? c.GetRequiredService<FooService>() as IService 
     : c.GetRequiredService<BarService>() as IService 
); 

Я не знаю, как реализовать проверку IsThisTheFooArea.

Как получить доступ к HttpContext или что-то подобное, чтобы я мог проверить текущий маршрут?

ответ

2

Вот способ:

ConfigureServices.cs:

 services.AddSingleton<IActionContextAccessor, ActionContextAccessor>(); 
     services.AddScoped<IService>(provider => 
     { 
      var actionContextAccessor = provider.GetService<IActionContextAccessor>(); 
      var descriptor = actionContextAccessor.ActionContext.ActionDescriptor as ControllerActionDescriptor; 
      var areaName = descriptor.ControllerTypeInfo.GetCustomAttribute<AreaAttribute>().RouteValue; 
      if(areaName == "FooArea") 
      { 
       return new FooService(); 
      } 
      else 
      { 
       return new BarService(); 
      } 
     }); 

Услуги:

public interface IService { string DoThisThing(); } 

public class FooService : IService 
{ 
    public string DoThisThing() 
    { 
     return "Foo"; 
    } 
} 

public class BarService : IService 
{ 
    public string DoThisThing() 
    { 
     return "Bar"; 
    } 
} 

И контроллеры:

[Area("FooArea")] 
public class FooController : Controller 
{ 
    private readonly IService _service; 

    public FooController(IService service) 
    { 
     _service = service; 
    } 

    public IActionResult Index() 
    { 
     return Content(_service.DoThisThing()); 
    } 
} 

[Area("BarArea")] 
public class BarController : Controller 
{ 
    private readonly IService _service; 

    public BarController(IService service) 
    { 
     _service = service; 
    } 

    public IActionResult Index() 
    { 
     return Content(_service.DoThisThing()); 
    } 
} 
+0

Спасибо, это работает. (... но ничего себе, так много обручей, чтобы перепрыгнуть через что-то настолько простое.) – grokky

+0

Кроме того, я вспоминаю прочтение на странице проекта github, что 'ActionContextAccessor' не зарегистрирован по умолчанию, поскольку это дорого, так что жаль, что нет более простой способ. Он работает, хотя и достаточно хорош для моих нужд. – grokky

+0

Требуется для получения информации о зоне. Я не знаю, есть ли другой способ получить название области. Можно использовать путь запроса (часть области), но в этом случае вам нужно будет ввести «HttpContextAccessor», и я думаю, что это нехорошо. –

-1

Вам необходимо либо реализовать (или найти реализацию на основе) IControllerFactory, либо IDependencyResolver и установить его при запуске приложения, чтобы ввести зависимости контроллера.

ControllerBuilder.Current.SetControllerFactory(new MyControllerFactory(container)); 

// Or... 

DependencyResolver.SetResolver(new MyDependencyResolver(container)); 

Подробнее https://www.asp.net/mvc/overview/older-versions/hands-on-labs/aspnet-mvc-4-dependency-injection

+1

Это не для Core. Кроме того, мне не нужно вводить в контроллеры. – grokky

Смежные вопросы