C# 在运行时从 appSettings.json 注入特定项目
C# Injecting Specific Item from appSettings.json at runtime
如何根据运行时输入值从 C# .NET Core Web API 中的数组 appSettings.json 注入特定设置(可能很多)?
appSettings.json:
{
"SettingProfiles": [
{
"Name": "Profile1",
"SettingA": "SettingAValue1",
"SettingB": "SettingBValue1"
},
{
"Name": "Profile2",
"SettingA": "SettingAValue2",
"SettingB": "SettingBValue2"
}
...
}
设置类:
public class Settings {
public List<SettingsProfile> SettingsProfiles { get; set; }
}
public class SettingsProfile {
public string Name { get; set; };
public string SettingA { get; set; };
public string SettingB { get; set; };
}
服务class:
public class MyService : IMyService {
private readonly SettingsProfile _Profile;
public MyService(SettingsProfile profile) {
_Profile = profile;
}
public void DoStuff() {
Console.WriteLine($"Setting A: {_SettingsProfile.SettingA}, Setting B: {_SettingsProfile.SettingB}")
}
}
用户将输入他们想要应用的设置名称。如果在 Startup.cs 中配置了服务,我不确定如何执行此操作,此时我还没有要使用的设置。
我知道“更新”服务是一种不好的做法,尽管这是我能弄清楚如何让它工作的唯一方法:
public class MyController {
private readonly Settings _Settings;
public MyController(Settings settings) {
_Settings = settings;
}
public IActionResult DoStuff(profileName) {
SettingsProfile profile = _Settings.Where(profile => profile.Name == profileName);
MyService service = new Service(profile);
}
}
我显然遗漏了一些东西,但我一直在观看关于依赖注入的 YouTube 视频并阅读 Whosebug 直到我的眼睛流血,但我还没有弄明白。有人可以帮我制定一个我应该遵循的模式吗?
这就是我认为它应该工作的方式。
如果你使用另一种模式,它会更干净:Factory。
interface ISettingServiceFactory{
MyService GetService(string profileName);
}
class SettingServiceFactory: ISettingServiceFactory
{
MyService GetService(string profileName){
}
}
现在您可以通过两种方式实施GetService
。
第一个是像您在控制器中那样创建新的,并没有那么糟糕,因为这是工厂的目的。通过这种方式,您可以将该逻辑转移到其他地方。
第二个会有点丑,但像这样
interface ISettingServiceFactory{
MyService GetService(string profileName);
void SetCurrentProfile(SettingsProfile profile);
}
class SettingServiceFactory: ISettingServiceFactory
{
private IServiceProvider _serviceProvider;
private Settings _Settings;
public SettingServiceFactory(IServiceProvider serviceProvider,Settings settings){
_serviceProvider = serviceProvider;
_Settings = settings;
}
MyService GetService(string profileName){
var service = _serviceProvider.GetRequiredService<MyService>();
var profile = _Settings.Where(profile => profile.Name == profileName);
service.SetCurrentProfile(profile);
return service;
}
}
第二种方法只有在 MyService
的实现本身有很多其他依赖项并且您想不惜一切代价避免 new
时才有用。
在这两种情况下,您都将在控制器中注入工厂
public MyController(ISettingServiceFactory settingServiceFactory) {
_settingServiceFactory= settingServiceFactory;
}
public IActionResult DoStuff(profileName) {
MyService service = _settingServiceFactory.GetService(profileName)
}
如何根据运行时输入值从 C# .NET Core Web API 中的数组 appSettings.json 注入特定设置(可能很多)?
appSettings.json:
{
"SettingProfiles": [
{
"Name": "Profile1",
"SettingA": "SettingAValue1",
"SettingB": "SettingBValue1"
},
{
"Name": "Profile2",
"SettingA": "SettingAValue2",
"SettingB": "SettingBValue2"
}
...
}
设置类:
public class Settings {
public List<SettingsProfile> SettingsProfiles { get; set; }
}
public class SettingsProfile {
public string Name { get; set; };
public string SettingA { get; set; };
public string SettingB { get; set; };
}
服务class:
public class MyService : IMyService {
private readonly SettingsProfile _Profile;
public MyService(SettingsProfile profile) {
_Profile = profile;
}
public void DoStuff() {
Console.WriteLine($"Setting A: {_SettingsProfile.SettingA}, Setting B: {_SettingsProfile.SettingB}")
}
}
用户将输入他们想要应用的设置名称。如果在 Startup.cs 中配置了服务,我不确定如何执行此操作,此时我还没有要使用的设置。
我知道“更新”服务是一种不好的做法,尽管这是我能弄清楚如何让它工作的唯一方法:
public class MyController {
private readonly Settings _Settings;
public MyController(Settings settings) {
_Settings = settings;
}
public IActionResult DoStuff(profileName) {
SettingsProfile profile = _Settings.Where(profile => profile.Name == profileName);
MyService service = new Service(profile);
}
}
我显然遗漏了一些东西,但我一直在观看关于依赖注入的 YouTube 视频并阅读 Whosebug 直到我的眼睛流血,但我还没有弄明白。有人可以帮我制定一个我应该遵循的模式吗?
这就是我认为它应该工作的方式。 如果你使用另一种模式,它会更干净:Factory。
interface ISettingServiceFactory{
MyService GetService(string profileName);
}
class SettingServiceFactory: ISettingServiceFactory
{
MyService GetService(string profileName){
}
}
现在您可以通过两种方式实施GetService
。
第一个是像您在控制器中那样创建新的,并没有那么糟糕,因为这是工厂的目的。通过这种方式,您可以将该逻辑转移到其他地方。
第二个会有点丑,但像这样
interface ISettingServiceFactory{
MyService GetService(string profileName);
void SetCurrentProfile(SettingsProfile profile);
}
class SettingServiceFactory: ISettingServiceFactory
{
private IServiceProvider _serviceProvider;
private Settings _Settings;
public SettingServiceFactory(IServiceProvider serviceProvider,Settings settings){
_serviceProvider = serviceProvider;
_Settings = settings;
}
MyService GetService(string profileName){
var service = _serviceProvider.GetRequiredService<MyService>();
var profile = _Settings.Where(profile => profile.Name == profileName);
service.SetCurrentProfile(profile);
return service;
}
}
第二种方法只有在 MyService
的实现本身有很多其他依赖项并且您想不惜一切代价避免 new
时才有用。
在这两种情况下,您都将在控制器中注入工厂
public MyController(ISettingServiceFactory settingServiceFactory) {
_settingServiceFactory= settingServiceFactory;
}
public IActionResult DoStuff(profileName) {
MyService service = _settingServiceFactory.GetService(profileName)
}