I've got an ASP.NET Core application and I'd like to use different strategies based on the Route selected. As an example if someone navigates to /fr/Index I want to inject the French translation implementation into my Controller. Likewise when someone navigates to /de/Index I'd like the German translation injected.
This is to avoid having every single action on my Controller read the "language" parameter and pass it on.
From a higher level, I'd like to have something like that:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// Stuff here
app.MapWhen(
context => context.Request.Query["language"] == "fr",
builder =>
{
builder.Register<ILanguage>(FrenchLanguageImplementation);
});
app.MapWhen(
context => context.Request.Query["language"] == "de",
builder =>
{
builder.Register<ILanguage>(GermanLanguageImplementation);
});
}
Unfortunately, it doesn't look like I get the IoC container resolving context at that level.
PS: I'm using Lamar as IoC.
You can use the AddScoped
overload on IServiceCollection
(or ServiceRegistry
, which also implements IServiceCollection
) to provide a factory-based service registration to the DI container. Here's an example implementation of ConfigureContainer
, with explanatory comments inline:
public void ConfigureContainer(ServiceRegistry services)
{
// ...
// Register IHttpContextAccessor for use in the factory implementation below.
services.AddHttpContextAccessor();
// Create a scoped registration for ILanguage.
// The implementation returned from the factory is tied to the incoming request.
services.AddScoped<ILanguage>(sp =>
{
// Grab the current HttpContext via IHttpContextAccessor.
var httpContext = sp.GetRequiredService<IHttpContextAccessor>().HttpContext;
string requestLanguage = httpContext.Request.Query["language"];
// Determine which implementation to use for the current request.
return requestLanguage switch
{
"fr" => FrenchLanguageImplementation,
"de" => GermanLanguageImplementation,
_ => DefaultLanguageImplementation
};
});
}
Disclaimer: Up until testing the information in this answer, I've never used Lamar, so this Lamar-specific setup is taken from the docs and a best-guess effort. Without Lamar, the first line in the sample code would be public void ConfigureServices(IServiceCollection services)
with no other changes.