我的项目是一个带有.NET 8的Windows后台服务。
我想在我当前的项目中使用 Microsoft Entity Framework Core。我还想使用
DbContextFactory
在需要的地方创建一个实例。
因此我需要在我的
Program.cs
文件中进行设置。
实际上我需要多解释一下我当前项目的设置。
appsettings.json
中有一个属性值,它控制应使用哪个数据库。
这是我的
appsettings.json
:
...
{
"AppSettings": {
"DaysBetweenExecution": 1,
"ExecutionHour": 3,
"ExecutionMinute": 0,
"Environment": "Dev"
},
...
如您所见,环境设置为
Dev
。
所以我在我的
AppSettings
中设置了这个Program.cs
,如下所示:
...
builder.Services.AddOptions<AppSettings>()
.BindConfiguration("AppSettings");
...
在我的应用程序中使用这些设置。
AppSettings
类看起来像这样:
namespace BrochureCreationService.ApplicationLogic.Models.AppSettings
{
public class AppSettings
{
public int DaysBetweenExecution { get; set; } = -1;
public int ExecutionHour { get; set; } = -1;
public int ExecutionMinute { get; set; } = -1;
public string Environment { get; set; } = "Dev";
}
}
这个值
Dev
正在由类 Environment
处理。
这是
Environment
课程:
using Microsoft.Extensions.Options;
namespace BrochureCreationService.ApplicationLogic.Models.Enviroment
{
public class Environment : IEnvironment
{
private IOptions<AppSettings.AppSettings> _AppSettings;
public Enums.Environment Current { get; set; }
public Environment(IOptions<AppSettings.AppSettings> appSettings) {
_AppSettings = appSettings;
Current = GetEnvironmentFromAppSettings();
}
public Enums.Environment GetEnvironmentFromAppSettings()
{
switch(_AppSettings.Value.Environment.ToLower())
{
case "dev":
return Enums.Environment.Dev;
case "test":
return Enums.Environment.Test;
case "ittest":
case "it-test":
return Enums.Environment.ITTest;
case "live":
case "production":
return Enums.Environment.Live;
default:
return Enums.Environment.Dev;
}
}
public string GetConnectionString()
{
switch (_Environment.Current)
{
case Enums.Environment.Live:
return "connection string";
case Enums.Environment.Test:
return "connection string test";
case Enums.Environment.ITTest:
return "connection string it test";
case Enums.Environment.Dev:
return "connection string dev";
default:
return "connection string dev";
}
}
}
}
如您所见,
AppSettings
被注入到构造函数中。该类根据 Environment
中的 appsettings.json
设置为我提供了正确的连接字符串。
现在我的问题:我需要在
Program.cs
中设置 Entity Framework Core 的工厂。
我想这样做:
builder.Services.AddDbContextFactory<IMP_GG_Context>(options =>
{
var environment = new BrochureCreationService.ApplicationLogic.Models.Enviroment.Environment();
options.UseSqlServer(environment.GetConnectionString());
}, ServiceLifetime.Scoped);
这里的问题是,这条线不起作用:
var environment = new BrochureCreationService.ApplicationLogic.Models.Enviroment.Environment();
...因为
Environment
在构造函数中需要 AppSettings
或更好的 IOptions<AppSettings.AppSettings>
。我怎样才能在Program.cs
中管理它?
或者有更好的方法吗?
也许吧,如果有帮助的话。这是我当前的完整代码
Program.cs
:
using Microsoft.Extensions.Logging.Configuration;
using Microsoft.Extensions.Logging.EventLog;
using BrochureCreationService.GUI;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddWindowsService(options =>
{
options.ServiceName = "Brochure Creation Service";
});
LoggerProviderOptions.RegisterProviderOptions<EventLogSettings, EventLogLoggerProvider>(builder.Services);
builder.Services.AddOptions<AppSettings>().BindConfiguration("AppSettings");
builder.Services.AddOptions<WordSettings>().BindConfiguration("WordSettings");
builder.Services.AddOptions<PdfSettings>().BindConfiguration("PdfSettings");
builder.Services.AddOptions<EmailSettings>().BindConfiguration("EmailSettings");
builder.Services.AddSingleton<IEnvironment, BrochureCreationService.ApplicationLogic.Models.Enviroment.Environment>();
builder.Services.AddSingleton<IServiceController, ServiceController>();
builder.Services.AddTransient<IExecution, Execution>();
//... some more dependencies with AddTransient
builder.Services.AddScoped<IIMP_GG_Context, IMP_GG_Context>();
builder.Services.AddDbContextFactory<IMP_GG_Context>(options =>
{
var appSettingsOptions = Configuration.GetSection("AppSettings").Get<AppSettings>();
var environment = new BrochureCreationService.ApplicationLogic.Models.Enviroment.Environment(appSettingsOptions);
options.UseSqlServer(environment.GetConnectionString());
}, ServiceLifetime.Scoped);
builder.Services.AddHostedService<WindowsBackgroundService>();
IHost host = builder.Build();
host.Run();
提前非常感谢您的任何提示或帮助。
首先,我强烈建议您使用应用程序密钥。将
ConnectionString
保留在源代码管理中并不安全。
阅读以下文章以了解此功能的使用: https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets
因此,对于您的 DI 问题,您只需添加以下代码即可:
var options = Configuration.GetSection("AppSettings").Get<AppSettings>();
您可以使用此选项创建
Environment
的新实例。