根据Route在Controller中注入不同的实现
Inject different implementions in Controller based on Route
我有一个 ASP.NET 核心应用程序,我想根据所选的路线使用不同的策略。
例如,如果有人导航到 /fr/Index,我想将法语翻译实现注入到我的控制器中。
同样,当有人导航到 /de/Index 时,我希望插入德语翻译。
这是为了避免我的控制器上的每一个动作都读取“语言”参数并传递它。
从更高的层次,我想要这样的东西:
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);
});
}
不幸的是,我似乎没有在该级别获得 IoC 容器解析上下文。
PS:我使用 Lamar 作为 IoC。
您可以在 IServiceCollection
(或 ServiceRegistry
上使用 AddScoped
重载,它也实现了 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
};
});
}
免责声明:在测试此答案中的信息之前,我从未使用过 Lamar,因此此特定于 Lamar 的设置取自文档和最佳猜测结果。如果没有 Lamar,示例代码中的第一行将是 public void ConfigureServices(IServiceCollection services)
,没有其他更改。
我有一个 ASP.NET 核心应用程序,我想根据所选的路线使用不同的策略。 例如,如果有人导航到 /fr/Index,我想将法语翻译实现注入到我的控制器中。 同样,当有人导航到 /de/Index 时,我希望插入德语翻译。
这是为了避免我的控制器上的每一个动作都读取“语言”参数并传递它。
从更高的层次,我想要这样的东西:
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);
});
}
不幸的是,我似乎没有在该级别获得 IoC 容器解析上下文。
PS:我使用 Lamar 作为 IoC。
您可以在 IServiceCollection
(或 ServiceRegistry
上使用 AddScoped
重载,它也实现了 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
};
});
}
免责声明:在测试此答案中的信息之前,我从未使用过 Lamar,因此此特定于 Lamar 的设置取自文档和最佳猜测结果。如果没有 Lamar,示例代码中的第一行将是 public void ConfigureServices(IServiceCollection services)
,没有其他更改。