【问题标题】:Issue with Injecting strongly typed configuration setting in dot net core在 dot net core 中注入强类型配置设置的问题
【发布时间】:2018-12-21 11:04:43
【问题描述】:

我们有一个通用类库项目,其中有一个名为 myClass 的类,它实现了 IMyClass。

public class MyClass : IMyClass
{       
    private readonly string _myConfigPath;     

    public TimeSheet(MyConfigPath myConfigPath)
    {            
        _myConfigPath= myConfigPath.Value;
    }
    public void GetData(int id)
    {
         var values= _myConfigPath;
    }
}
public interface IMyClass
{
    void GetData(int id);
}

我的 MyConfigPath 类是从 ConfigInjector.ConfigurationSetting 抽象类扩展而来的。

public class MyConfigPath  : ConfigurationSetting<string>
{

}

在旧项目中,我们使用 AutoFac 通过 ConfigInjector 注入配置设置。

但是现在我们在一个基于 .Net Core2.1 的新项目上,我们必须使用用 MyClass 编写的业务逻辑。

虽然我可以像这样在新项目的控制器中注入 IMyClass 类型

   services.ConfigurePOCO<MyConfigPath>(configuration.GetSection("AppSettings:MyConfigPath"));
 services.AddTransient<IMyClass , MyClass>();

但分配给 _myConfigPath 的值仍然为空,因为我们没有为 configinjector 提供任何配置信息。

我已尝试关注 StrathWeb BlogRick Strahl's Web Log 但这些仅适用于强类型对象,但不适用于 configinjector。

两种方法我都试过了

 services.Configure<MyConfigPath >(configuration.GetSection("AppSettings:MyConfigPath "));

并创建StrathWeb Blog指定的扩展方法。

  services.ConfigurePOCO<MyConfigPath>(configuration.GetSection("AppSettings:MyConfigPath"));

这里更改类库项目的机会很少,因为许多其他尚未在 .net 核心上的项目都在使用它。 这是我的 appsettings.json 文件的方式

{
 "AppSettings": {
  "MyConfigPath": "C:\\EmployeeUpload"
  }
}

任何帮助将不胜感激。

【问题讨论】:

    标签: asp.net-core .net-core asp.net-core-mvc asp.net-core-2.0 asp.net-core-webapi


    【解决方案1】:

    我找到了解决我所面临问题的方法。在这里使用反射帮助了我。

    下面是解决办法

    var type= typeof(MyConfigPath);
    var t = Activator.CreateInstance(type);
    PropertyInfo propertyInfo = type.GetProperty("Value");
    var configValue = configuration.GetValue<string>($"AppSettings:{type.Name}");
    if (!string.IsNullOrEmpty(configValue) && propertyInfo != null)
    {
      propertyInfo.SetValue(t, configValue, null);
    }
    services.AddSingleton(type, t);
    

    通过这种方式,我能够注入我的强类型类。我使用反射是因为我必须对类库中的许多类型做同样的事情。

    我通过一些研发和与我的团队的一些讨论得到了这个想法。

    【讨论】:

      【解决方案2】:

      首先,如果您使用.Configure 方法,您将不会注入MyConfigPath,而是IOptions&lt;MyConfigPath&gt;(再看看您的第一个链接)。所以你的注入变成了这样:

      public MyClass(IOptions<MyConfigPath> myConfigPathOptions)
      

      其次,configuration.GetSection 旨在访问整个部分,而不仅仅是一个字符串。如果您想直接从 JSON 访问“MyConfigPath”,您可以使用configuration["AppSettings:MyConfigPath"]。您可以像configuration.GetSection("AppSettings") 一样使用GetSection,将所有应用程序设置作为一个整体。

      我建议您查看 IConfigurationIOptions 的文档

      我假设你真正想做的是这样的:

      为你的所有设置设置一个类:

      public class MyAppSettings {
          public string MyConfigPath {get; set;} 
          public int MyOtherSetting { get; set; } // sample of how you could have more
      }
      

      上面添加了“MyOtherSetting”的 json 看起来像这样:

      {
          "AppSettings": {
              "MyConfigPath": "C:\\EmployeeUpload",
              "MyOtherSetting" : 501
          }
      }
      

      在你的启动类中,你可以使用这个:

      services.Configure<MyAppSettings>(configuration.GetSection("AppSettings")
      

      现在,对于注射,您将需要使用以下内容:

      MyClass(IOptions<MyAppSettings> settingOptions)
      {            
          _myConfigPath = myConfigPath.Value.MyConfigPath;
      }
      

      【讨论】:

      • 感谢@Neville Nazerane,实际上我无法更改 MyClass 的构造函数。它应该保持原样。我可以通过提供这样的键来访问配置键的值:“AppSettings:MyConfigPath”。它确实有效。
      • 你的意思是你的注射有效?你发现myConfigPath.Value 是空的吧?
      • 无论哪种方式,使用services.AddSingleton 应该可以帮助您保持结构
      • 是的,注入工作正常,myConfigPath.Value 为空。这里的 Value 是抽象类 ConfigurationSetting 的属性。
      • 我想要的是:myConfigPath.Value 不应该为空。它应该从配置中分配,从启动注入..
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-23
      • 1970-01-01
      • 2019-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-13
      相关资源
      最近更新 更多