我建议不要通过AppSettings。一个类不应该依赖于模糊的东西——它应该完全依赖于它需要的东西,或者接近它。 ASP.NET Core 使摆脱依赖AppSettings 的旧模式变得更加容易。如果您的类依赖于AppSettings,那么您无法从构造函数中真正看到它依赖于什么。它可能取决于任何键。如果它依赖于一个更具体的接口,那么它的依赖就更清晰、更明确,并且您可以在单元测试时模拟该接口。
您可以使用您的类需要的特定设置(或不太具体但不太宽泛的设置)和实现它的类创建一个接口 - 例如,
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<Foo> FooList { get; set; }
public IEnumerable Foos
{
get
{
if (FooList == null) FooList = new List<Foo>();
return FooList.Cast<IFoo>();
}
}
}
public class Foo : IFoo
{
public string Color { get; set; }
public double BarUnits { get; set; }
}
然后添加一个.json文件,fooSettings.json:
{
"FooSettings": {
"Name": "MyFooSettings",
"FooList": [
{
"Color": "Red",
"BarUnits": "1.5"
}, {
"Color": "Blue",
"BarUnits": "3.14159'"
}, {
"Color": "Green",
"BarUnits": "-0.99999"
}
]
}
}
然后,在 Startup()(在 Startup.cs 中)中,我们指定 Configuration 中的内容,添加 fooSettings.json:
var builder = new ConfigurationBuilder(appEnv.ApplicationBasePath)
.AddJsonFile("config.json")
.AddJsonFile($"config.{env.EnvironmentName}.json", optional: true)
.AddJsonFile("fooSettings.json");
最后,在 ConfigureServices()(也在 Startup.cs 中)告诉它加载 FooSettings 的实例,将其转换为 IFooSettings(因此属性显示为只读)并为所有用户提供该单个实例依赖IFooSettings:
var fooSettings = (IFooSettings)ConfigurationBinder.Bind<FooSettings>(
Configuration.GetConfigurationSection("FooSettings"));
services.AddInstance(typeof (IFooSettings), fooSettings);
现在您的类 - 控制器、过滤器或由 DI 容器创建的任何其他内容 - 可以依赖于 IFooSettings,它将由 .json 文件提供。但是您可以模拟 IFooSettings 进行单元测试。
Original blog post - 这是我的,所以我没有抄袭。