Внедрение значений конфигурации в ASP .NET Core 2.1
Как и в случае с другими, я не согласен с внедрением IOptions в каждую службу, которая может в ней нуждаться, и искал другие варианты. Моей целью было ввести ценности, необходимые сервису, и ничего более. Я придумал следующее, которое работает и функционирует, но является ли оно твердым и обслуживаемым? Кажется слишком простым и эффективным, как будто я что-то упустил.
Требования:
- загрузить пользовательский файл JSON
- строго типизированный
- не выставлять больше, чем необходимо
- ремонтопригодны
Я придумал следующее.
public Startup(IConfiguration configuration)
{
var configBuilder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile("myappsettings.json", optional: false, reloadOnChange: true)
.AddEnvironmentVariables()
;
Configuration = configBuilder.Build();
}
Использование LAMAR, так что следующее:
public void ConfigureContainer(ServiceRegistry services)
{
var config = new MyAppConfig();
Configuration.GetSection("MyAppConfig").Bind(config);
}
Мой файл JSON выглядит так:
{
"MyAppConfig": {
"AppSettings": {
"Name": "My Application"
},
"DataSettings": {
"PrimaryDB": {
"Name": "DBNAME",
"ConnectionString": "Server=serverAddr.DOMAIN.com;Database=INITIAL_DB_HERE;User Id=MY_APP_USER_NAME;Password=******;MultipleActiveResultSets=true",
"DatabaseName": "DBNAME", // this has a separate use
"Provider": ""
}
}
}
}
Чтобы использовать это, я просто передаю объект config в функцию, которая создает экземпляр службы, и внедряю в службу только то, что нужно.
services.For<IPerformanceService>().Use(c => CreatePerformanceService(config));
private IPerformanceService CreatePerformanceService(IAppConfiguration appConfig)
{
var myRepo = new PerformanceRepository(appConfig.DataSettings.PrimaryDB.ConnectionString, appConfig.DataSettings.PrimaryDB.DatabaseName);
return new PerformanceService(myRepo);
}
1 ответ
Я не думаю, что у этого есть определенный ответ, больше о том, что вы считаете удобным для вас. Для себя я пошел немного другим подходом.
Это запуск:
// Redis Caching
var redisConfiguration = configuration.GetSection("Redis").Get<RedisConfiguration>();
services.AddSingleton(redisConfiguration);
services.AddSingleton<RedisCacheHelper>();
Эта часть в значительной степени то, что вы делаете, класс для хранения значений конфигурации. Обратите внимание, что вам не нужно "связывать", вы можете напрямую использовать.Get для анализа конфигурации в классе.
Я добавляю свою конфигурацию в синглтон, чтобы я мог использовать обычный DI, чтобы вставить его в конструктор, где бы он мне ни понадобился. В этом случае он используется только для CacheHelper, но у меня есть другие места, где конфиг используется несколькими контроллерами и промежуточным ПО.
Использование конфига только для внутреннего DI:
public class RedisCacheHelper
{
public StackExchangeRedisCacheClient Cache {get;set;}
public RedisCacheHelper(RedisConfiguration redisconfig)
{
Cache = new StackExchangeRedisCacheClient(new NewtonsoftSerializer(),redisconfig );
}
}