Asp.net core 如何替换ASP.NET核心中的依赖项?

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) { 因此,

在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) {
公共索引模型(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
,容器会将其提供给您的类。我将编辑我的答案以使事情更清楚。