C# 如何将IConfiguration绑定到构造函数中具有参数的类

C# 如何将IConfiguration绑定到构造函数中具有参数的类,c#,asp.net-core,.net-core,C#,Asp.net Core,.net Core,我正在使用ASP.NET核心应用程序的标准配置模式,我无法将配置绑定到我的类,因为它具有参数construtor 在appsettings.json中,我包含了所需的配置: "MyServiceConfig": { "Identity": { "Version": "1.0", "ComplicatedUri": { "Scheme": "http", "Authority": "localhost",

我正在使用ASP.NET核心应用程序的标准配置模式,我无法将配置绑定到我的类,因为它具有参数construtor

在appsettings.json中,我包含了所需的配置:

    "MyServiceConfig": {
      "Identity": {
        "Version": "1.0",
        "ComplicatedUri": {
          "Scheme": "http",
          "Authority": "localhost",
          "Path": "SuperService"
        }
      }
    },
我的配置类及其依赖项如下所示:

        public class MyServiceConfig
        {
            public MyIdentity Identity { get; set; }
        }

        public class MyIdentity
        {
            public string IdentityName { get; set; }
            public string Version { get; set; }
            public MyComplicatedUri ComplicatedProperty { get; set; }

            public MyIdentity(string version, MyComplicatedUri complicatedProperty)
            {
                Version = version;
                ComplicatedProperty = complicatedProperty;
                IdentityName = complicatedProperty.Path;
            }
        }

        public class MyComplicatedUri
        {
            public string Scheme { get; set; }
            public string Authority { get; set; }
            public string Path { get; set; }
        }
        private MyServiceConfig GetMyConfig(IConfiguration configuration)
        {
            var config = new MyServiceConfig();
            configuration.GetSection("MyServiceConfig").Bind(config);
            return config;
        }
我已经尝试过这样的代码:

        public class MyServiceConfig
        {
            public MyIdentity Identity { get; set; }
        }

        public class MyIdentity
        {
            public string IdentityName { get; set; }
            public string Version { get; set; }
            public MyComplicatedUri ComplicatedProperty { get; set; }

            public MyIdentity(string version, MyComplicatedUri complicatedProperty)
            {
                Version = version;
                ComplicatedProperty = complicatedProperty;
                IdentityName = complicatedProperty.Path;
            }
        }

        public class MyComplicatedUri
        {
            public string Scheme { get; set; }
            public string Authority { get; set; }
            public string Path { get; set; }
        }
        private MyServiceConfig GetMyConfig(IConfiguration configuration)
        {
            var config = new MyServiceConfig();
            configuration.GetSection("MyServiceConfig").Bind(config);
            return config;
        }
它抛出异常:

'Cannot create instance of type 'MyIdentity' because it is missing
a public parameterless constructor.'
这种行为在某些情况下是有道理的,但在特定的情况下就不那么有道理了。映射可以是直接的-通过具有公共setter的属性名或构造函数参数名

另一个想法是在启动类的AddJsonOptions中为我的类型-IConfiguration添加转换器。Bind可以推断如何构造它,但我也尝试了,但没有成功

您是否遇到过类似的问题并找到了合理的解决方案


编辑:添加无参数构造函数当然可以,但有时我需要处理外部包中的一些类,我想将它们用作配置类的一部分,所以假设我们不能修改它们。我希望避免只为映射添加新类型。理想情况下,我希望强制ASP.NET核心引擎使用带有参数的现有构造函数和带有json属性的按参数名称映射-这目前不起作用。

您应该在MyIdentity类中添加一个默认构造函数。 .bind使用默认构造函数将配置绑定到对象中。 因此,在MyIdentity类中添加所需的默认构造函数就可以了

public MyIdentity(){}
此外,您还可以使用

在ConfigureServices中,添加以下内容:

services.AddOptions();
services.ConfigureOptions<MyServiceConfig>();
然后使用依赖项注入对其进行初始化。
另外,使用您自己的

您应该在MyIdentity类中添加一个默认构造函数。 .bind使用默认构造函数将配置绑定到对象中。 因此,在MyIdentity类中添加所需的默认构造函数就可以了

public MyIdentity(){}
此外,您还可以使用

在ConfigureServices中,添加以下内容:

services.AddOptions();
services.ConfigureOptions<MyServiceConfig>();
然后使用依赖项注入对其进行初始化。
此外,如果您计划验证值,则使用您自己的

如图所示的构造函数更有意义,我会这样做。如果我的应用程序需要IdentityName设置,但配置中缺少该设置,我更希望在启动时有一个异常,它会大叫:“嘿,缺少这个重要的设置!”!我不希望该值为null,在代码的某些完全不同的部分中得到一个NullReferenceException,并且必须开始追溯该值应该来自何处。是的,当然,我还认为该构造函数中应该包含一些其他内容。在我的项目中,类来自外部包,我试图复制它们的一些简单概念。我的例子不是最好的——我认为该字段的目的是从嵌套类中获取它,这是非常冗余的,但这只是我的推测。干杯如果您计划验证这些值,那么像图中所示的构造函数更有意义,我会这样做。如果我的应用程序需要IdentityName设置,但配置中缺少该设置,我更希望在启动时有一个异常,它会大叫:“嘿,缺少这个重要的设置!”!我不希望该值为null,在代码的某些完全不同的部分中得到一个NullReferenceException,并且必须开始追溯该值应该来自何处。是的,当然,我还认为该构造函数中应该包含一些其他内容。在我的项目中,类来自外部包,我试图复制它们的一些简单概念。我的例子不是最好的——我认为该字段的目的是从嵌套类中获取它,这是非常冗余的,但这只是我的推测。干杯当然,这一点很好,添加无参数构造函数是可行的,但有时我需要处理一些无法修改的类。如果没有其他选项,我会将其标记为接受答案。您可以创建自己的类,并将无法更改的现有类映射到该类。因此,现有类用于从配置中读取,然后使用它填充您自己的类的值。在这一步中,您可以验证。您还可以使自己的类不可变。这样你就可以使用你不能更改的类,但你仍然可以得到验证和不变性的好处。当然,这是一个很好的观点,添加无参数构造函数是可行的,但有时我需要处理一些我不能修改的类。如果没有其他选项,我会将其标记为接受答案。您可以创建自己的类,并将无法更改的现有类映射到该类。因此,现有类用于从配置中读取,然后使用它填充您自己的类的值。在这一步中,您可以验证。您还可以使自己的类不可变。这样,您就可以使用无法更改的类,但仍然可以获得验证和验证的好处 不变性。