简体   繁体   中英

How to bind IConfiguration to class having parameters in constructor

I am using standard configuration pattern for ASP.NET Core applications and I can not bind configuration to my class as it has construtor with parameters.

In appsettings.json I included desired config:

    "MyServiceConfig": {
      "Identity": {
        "Version": "1.0",
        "ComplicatedUri": {
          "Scheme": "http",
          "Authority": "localhost",
          "Path": "SuperService"
        }
      }
    },

My config class and it's dependencies look like that:

        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; }
        }

I have already tried code like that:

        private MyServiceConfig GetMyConfig(IConfiguration configuration)
        {
            var config = new MyServiceConfig();
            configuration.GetSection("MyServiceConfig").Bind(config);
            return config;
        }

It throws exception:

'Cannot create instance of type 'MyIdentity' because it is missing
a public parameterless constructor.'

That behaviour can make sense in some cases but in that particular one not so much. Mappings could be straightforward - by property names which have public setters or by constructor parameter names.

Another idea would be adding converter in AddJsonOptions in Startup class for my types - IConfiguration.Bind could infer how to construct it but I also tried that with no success.

Have you encoutered similar problems and found some reasonable solution to that?

Edit: Adding parameterless constructor will work of course, but sometimes I need to deal with some classes from external packages I'd like to use as parts of my config class so let's assume we can not modify them. I'd like to avoid adding new types for mapping only as well. Ideally I'd like to force ASP.NET Core engine to use existing constructor with parameters and by parameter name map with json properties - which currently is not working.

You should just add a default constructor in MyIdentity class. .bind() binds the configuration into the object using the default constructor. So, add the required default constructor in your MyIdentity class and it will be fine.

public MyIdentity(){}

Also , you can use Options .

In ConfigureServices , add the following:

services.AddOptions();
services.ConfigureOptions<MyServiceConfig>();

and then use dependency injection to initialize it. In addition, use your own JsonConverter

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM