C# - Microsoft Entity Framework Core 工厂 - 依赖注入

问题描述 投票:0回答:1

我的项目是一个带有.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();

提前非常感谢您的任何提示或帮助。

c# dependency-injection entity-framework-core factory
1个回答
0
投票

首先,我强烈建议您使用应用程序密钥。将

ConnectionString
保留在源代码管理中并不安全。

阅读以下文章以了解此功能的使用: https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets

因此,对于您的 DI 问题,您只需添加以下代码即可:

var options = Configuration.GetSection("AppSettings").Get<AppSettings>();

您可以使用此选项创建

Environment
的新实例。

© www.soinside.com 2019 - 2024. All rights reserved.