ASP.NET 5 DI app setting outside controller

后端 未结 4 1026

I can DI app setting in the controller like this

 private IOptions appSettings;
 public CompanyInfoController(IOptions appS         


        
4条回答
  •  甜味超标
    2021-01-21 06:14

    I recommend not passing AppSettings. A class shouldn't depend on something vague - it should depend on exactly what it needs, or close to it. ASP.NET Core makes it easier to move away from the old pattern of depending on AppSettings. If your class depends on AppSettings then you can't really see from the constructor what it depends on. It could depend on any key. If it depends on a more specific interface then its dependency is clearer, more explicit, and you can mock that interface when unit testing.

    You can create an interface with the specific settings that your class needs (or something less specific but not too broad) and a class that implements it - for example,

        public interface IFooSettings
        {
            string Name { get; }
            IEnumerable Foos { get; }
        }
    
        public interface IFoo
        {
            string Color { get;  }
            double BarUnits { get;  }
        }
    
        public class FooSettings : IFooSettings
        {
            public string Name { get; set; }
            public List FooList { get; set; }
    
            public IEnumerable Foos
            {
                get
                {
                    if (FooList == null) FooList = new List();
                    return FooList.Cast();
                }
            }
        }
    
        public class Foo : IFoo
        {
            public string Color { get; set; }
            public double BarUnits { get; set; }
        }
    

    Then add a .json file, fooSettings.json:

        {
          "FooSettings": {
            "Name": "MyFooSettings",
            "FooList": [
              {
                "Color": "Red",
                "BarUnits": "1.5"
              },      {
                "Color": "Blue",
                "BarUnits": "3.14159'"
              },      {
                "Color": "Green",
                "BarUnits": "-0.99999"
              }
            ]
          }
        }
    

    Then, in Startup() (in Startup.cs) where we specify what goes into our Configuration, add fooSettings.json:

        var builder = new ConfigurationBuilder(appEnv.ApplicationBasePath)
            .AddJsonFile("config.json")
            .AddJsonFile($"config.{env.EnvironmentName}.json", optional: true)
            .AddJsonFile("fooSettings.json");
    

    Finally, in ConfigureServices() (also in Startup.cs) tell it to load an instance of FooSettings, cast it as IFooSettings (so the properties appear read-only) and supply that single instance for all dependencies on IFooSettings:

        var fooSettings = (IFooSettings)ConfigurationBinder.Bind(
            Configuration.GetConfigurationSection("FooSettings"));
        services.AddInstance(typeof (IFooSettings), fooSettings);
    

    Now your class - controller, filter, or anything else created by the DI container - can have a dependency on IFooSettings and it will be supplied from the .json file. But you can mock IFooSettings for unit testing.

    Original blog post - it's mine so I'm not plagiarizing.

提交回复
热议问题