Я рекомендую не проходить 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
, преобразовать его как IFooSetting
s (чтобы свойства отображались только для чтения) и предоставить этот единственный экземпляр для всех зависимостей от IFooSettings
:
var fooSettings = (IFooSettings)ConfigurationBinder.Bind<FooSettings>(
Configuration.GetConfigurationSection("FooSettings"));
services.AddInstance(typeof (IFooSettings), fooSettings);
Теперь ваш класс — контроллер, фильтр или что-то еще, созданное контейнером DI — может иметь зависимость от IFooSettings
и будет поставляться из файла .json. Но вы можете издеваться над IFooSettings
для модульного тестирования.
Исходный пост в блоге - это мое, так что я не занимаюсь плагиатом.
person
Scott Hannen
schedule
28.04.2016