C# 基于路由在控制器中注入不同的实现
我有一个ASP.NET核心应用程序,我想根据选择的路线使用不同的策略。 例如,如果有人导航到/fr/Index,我希望将法语翻译实现注入到我的控制器中。 同样,当有人导航到/de/Index时,我希望插入德语翻译 这是为了避免让控制器上的每个动作都读取“language”参数并将其传递 从更高的层次来看,我想要这样的东西:C# 基于路由在控制器中注入不同的实现,c#,asp.net-core,ioc-container,lamar,C#,Asp.net Core,Ioc Container,Lamar,我有一个ASP.NET核心应用程序,我想根据选择的路线使用不同的策略。 例如,如果有人导航到/fr/Index,我希望将法语翻译实现注入到我的控制器中。 同样,当有人导航到/de/Index时,我希望插入德语翻译 这是为了避免让控制器上的每个动作都读取“language”参数并将其传递 从更高的层次来看,我想要这样的东西: public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // Stuff
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);
});
}
public void配置(IApplicationBuilder应用程序,IWebHostEnvironment环境)
{
//这里的东西
app.MapWhen(
context=>context.Request.Query[“language”]=“fr”,
生成器=>
{
生成器注册(法语实现);
});
app.MapWhen(
context=>context.Request.Query[“language”]=“de”,
生成器=>
{
建造商注册(德语语言实施);
});
}
不幸的是,我似乎没有在那个级别上获得IoC容器解析上下文
PS:我使用Lamar作为IoC。您可以使用IServiceCollection
上的重载(或ServiceRegistry
,它也实现IServiceCollection
)向DI容器提供基于工厂的服务注册。下面是ConfigureContainer
的一个示例实现,其中内嵌了解释性注释:
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
};
});
}
公共void配置容器(ServiceRegistry服务)
{
// ...
//注册IHttpContextAccessor以在下面的工厂实现中使用。
AddHttpContextAccessor();
//为ILanguage创建作用域注册。
//从工厂返回的实现与传入的请求相关联。
services.AddScoped(sp=>
{
//通过IHttpContextAccessor获取当前HttpContext。
var httpContext=sp.GetRequiredService().httpContext;
字符串requestLanguage=httpContext.Request.Query[“语言”];
//确定用于当前请求的实现。
返回请求语言开关
{
“fr”=>法语语言实现,
“de”=>德国语言实施,
_=>DefaultLanguageImplementation
};
});
}
免责声明:在测试此答案中的信息之前,我从未使用过Lamar,因此此Lamar特定设置取自文档和最佳猜测。如果没有Lamar,示例代码中的第一行将是
public void ConfigureServices(IServiceCollection services)
,没有其他更改。您可以通过context.Request.Query[“language”]
获得值吗?实际上我不确定。这是为了说明这一点。我当然不能对建筑商说“注册”。