Asp.net core 如何替换ASP.NET核心中的依赖项?
在startup.cs中,我们有:Asp.net core 如何替换ASP.NET核心中的依赖项?,asp.net-core,dependency-injection,Asp.net Core,Dependency Injection,在startup.cs中,我们有: public void ConfigureServices(IServiceCollection services) { services.AddLocalization(options => options.ResourcesPath = "Resources"); } public IndexModel(IStringLocalizer<Strings> localizer) { 因此,
public void ConfigureServices(IServiceCollection services)
{
services.AddLocalization(options => options.ResourcesPath = "Resources");
}
public IndexModel(IStringLocalizer<Strings> localizer) {
因此,我们的索引页面可以有以下内容:
public void ConfigureServices(IServiceCollection services)
{
services.AddLocalization(options => options.ResourcesPath = "Resources");
}
public IndexModel(IStringLocalizer<Strings> localizer) {
公共索引模型(IStringLocalizer){
我想将定位器
包装到另一个类中,并用包装器的一个单件替换它在IoC容器中的存在
问题在于,在COnfigureServices
方法中,似乎无法从容器中检索或删除条目
本质上,我希望替换AddLocalization
调用提供的已注册实例,这样就不需要替换解决方案中包装类注入的每个实例
这可能吗?您可以使用装饰器模式解决此问题 首先,配置服务,以便您可以直接访问
StringLocalizer
。这是针对MyLocalizer
类的,因为它需要的是StringLocalizer
类型的直接实例,而不是接口(IStringLocalizer
)。如果不注册,MyLocalizer将无法解析
services.AddTransient(typeof(StringLocalizer<>));
装饰器实现:
Decorator模式允许您向现有对象添加额外功能。假设IStringLocalizer
对象返回一个简单字符串,我需要将其设为大写
public class MyLocalizer<T> : IStringLocalizer<T>
{
public MyLocalizer(StringLocalizer<T> original)
{
_original = original;
}
private readonly StringLocalizer<T> _original;
// the decorator behavior is the same for all other methods.
// But for this particular method it adds a little feature to the original one! Beautiful :)
public LocalizedString this[string name] =>
new LocalizedString(name, _original[name].Value.ToUpper());
public LocalizedString this[string name, params object[] arguments] =>
_original[name, arguments];
public IEnumerable<LocalizedString> GetAllStrings(bool includeParentCultures) =>
_original.GetAllStrings(includeParentCultures);
public IStringLocalizer WithCulture(CultureInfo culture) =>
_original.WithCulture(culture);
}
公共类MyLocalizer:IStringLocalizer
{
公共MyLocalizer(StringLocalizer原件)
{
_原件=原件;
}
专用只读StringLocalizer_原件;
//装饰器行为与所有其他方法相同。
//但是对于这个特殊的方法,它在原来的方法上增加了一点特性!漂亮:)
public LocalizedString此[字符串名称]=>
新本地化字符串(名称,_original[name].Value.ToUpper());
public LocalizedString此[字符串名称,参数对象[]参数]=>
_原始[名称、参数];
公共IEnumerable GetAllStrings(bool includeParentCultures)=>
_原始.GetAllStrings(包括ParentCultures);
公共IStringLocalizer with culture(CultureInfo culture)=>
_原创。有文化(文化);
}
现在,依赖类中的任何内容都不会改变。它们只是使用MyLocalizer
而不是MVC的StingLocalizer
希望这有帮助!您不想将
本地化器
注入每个页面?只需使用在页面中具有本地化器
实例的静态类?本地化器已注入每个页面-我不想更新包含引用的每个文件。我想从DI容器,然后用我的包装器实例替换该本地化器。这需要删除现有的已注册实例。因此,请创建您自己的包装器,然后将IStringLocalizer本地化器
注入包装器构造函数,并在ConfigureServices
方法中注册包装器类。正在寻找类似以下内容:servAddSingleton(typeof(WrapperClass),解析器=>{var localizer=resolver.GetService();返回新的WrapperClass(localizer);})
@mohsen-esmailpour我会的,但这会让MS本地化留在容器中,我想用我的包装器替换已注册的类型,这样注入它的地方最终会得到我的类型,因此无需更新大量代码。我的理解是,服务在容器中注册了本地化程序es.AddLocalization()
调用,因此我无法选择它是否注册为transient。另外,您是说为已注册的类型注册具有指定类型的singleton会导致在注入原始类型时返回我的singleton吗?(实际上,覆盖注入类型的原始注册?@MattW容器始终为您提供最后注册的类型。我没有编写services.AddLocalization()
在我的代码中,我假设它是在所有这些之前编写的。所以您不必担心,因为在本例中,最后注册的类型是MyLocalizer
,容器会将其提供给您的类。我将编辑我的答案以使事情更清楚。