grokky grokky - 15 days ago 6
C# Question

Determine ASP.NET Core MVC Area during service registration


  • I'm using ASP.NET Core

  • My
    IService
    is registered with the DI container

  • There are two implementations:
    FooService
    and
    BarService

  • I must choose a service based on current request's MVC Area



So I need something like:

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


I don't know how to implement the
IsThisTheFooArea
check.

How do I access the
HttpContext
or something similar, so I can inspect the current route?

Answer

Here is a way:

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();
            }
        });

Services:

public interface IService { string DoThisThing(); }

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

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

And controllers:

[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());
    }
}
Comments