Может быть неправильное понимание задействованных концепций.
Configure<TOption>
зарегистрирует IOptions<TOptions>
.Теперь в вашем примере есть две отдельные регистрации.
Один раз при регистрации класса
services.AddScoped<InformationGetter>()
и другой при регистрации параметров.
Выполните следующие действия
//..
services.AddOptions();
//Adds IOptions<InformationGetter>
services.Configure<InformationGetter>(options => {
options.ConnectionString = Configuration.GetSection("Model").GetSection("ConnectionString").Value;
options.StoredProcedureName = "prInformationGetter";
});
//Adds InformationGetter but gets it from the registered options
services.AddScoped<InformationGetter>(sp =>
sp.GetRequiredService<IOptions<InformationGetter>>().Value
);
//...
Регистрация в области действия будет использовать фабричный делегат для извлечения зарегистрированных опций и возврата нужного типа.
public class InformationGetter {
public string ConnectionString { get; set; }
public string StoredProcedureName { get; set; }
//...
public string GetUserInformation(int userId) {
// Do SQL work
return info;
}
}
InformationGetter
выглядит как служба.
Я бы предложил рефакторинг в соответствии с более единым принципом ответственности (SRP) и разделением интересов (Soc).
//Needed by InformationGetter to perform its function
public class InformationGetterOptions {
public string ConnectionString { get; set; }
public string StoredProcedureName { get; set; }
}
//abstraction of InformationGetter
public interface IInformationGetter {
string GetUserInformation(int userId);
}
//implementation.
public class InformationGetter : IInformationGetter{
private readonly InformationGetterOptions options;
public InformationGetter(InformationGetterOptions options) {
this.options = options;
}
public string GetUserInformation(int userId) {
//use values in options to connect
// Do SQL work
return info;
}
}
Я бы вообще отказался от шаблона опций и просто зарегистрировал классиспользуя фабрику делегатов, извлекая то, что мне нужно из конфигурации.Таким образом, ваш код не будет тесно связан с проблемами инфраструктуры, такими как IOptions
public void ConfigureServices(IServiceCollection services) {
//...
InformationGetterOptions options = new InformationGetterOptions {
ConnectionString = Configuration.GetSection("Model").GetSection("ConnectionString").Value;
StoredProcedureName = "prInformationGetter";
};
services.AddSingleton(options);
services.AddScoped<IInformationGetter, InformationGetter>();
//...
}
Теперь IInformationGetter
можно вводить там, где это необходимо, и иметь все необходимые зависимости для выполнения своей функции.