【问题标题】:Inject data from database to a class with ASP.NET MVC Core使用 ASP.NET MVC Core 将数据库中的数据注入到类中
【发布时间】:2018-04-08 08:14:43
【问题描述】:

我想将一些电子邮件配置数据从数据库中注入到名为AuthMessageSenderOptions 的配置类中,该类具有以下属性:

public class AuthMessageSenderOptions
{
    public int PortNumber { get; set; }
    public string SmtpServer { get; set; }
    public string UserName { get; set; }
    public string Password { get; set; }
}

为了将appsettings.json 中的配置细节注入AuthMessageSenderOptions 类,我在Startup.cs 中使用了这段代码:

services.Configure<AuthMessageSenderOptions>(Configuration.GetSection("SMTP"));

现在我的问题是:

如何从数据库而不是 appsettings.json 读取这些数据并将它们注入我的 AuthMessageSenderOptions 类以供将来使用?

【问题讨论】:

  • 您是否使用实体框架连接到您的数据库?
  • @Isma 是的,实体框架

标签: c# asp.net-core asp.net-core-mvc asp.net-core-2.0


【解决方案1】:

您可以通过创建一个实现接口IConfigurationSource 的类并通过从ConfigurationProvider 继承来实现您的自定义配置提供程序来创建自定义配置源。

首先,创建一个配置源,用实体框架初始化数据源:

public class CustomMailConfigSource: IConfigurationSource
{
    private readonly Action<DbContextOptionsBuilder> _dbOptions;

    public CustomMailConfigSource(Action<DbContextOptionsBuilder> dbOptions)
    {
        _dbOptions = dbOptions;
    }

    public IConfigurationProvider Build(IConfigurationBuilder builder)
    {
        return new CustomMailConfigProvider(_dbOptions);
    }
}

然后,实现自定义配置提供程序:

public class CustomMailConfigProvider: ConfigurationProvider
{
    public CustomMailConfigProvider(Action<DbContextOptionsBuilder> dbOptions)
    {
        DbOptions = dbOptions;
    }

    Action<DbContextOptionsBuilder> DbOptions { get; }

    public override void Load()
    {
        var builder = new DbContextOptionsBuilder<ConfigurationContext>();
        DbOptions(builder);

        using (var dbContext = new ConfigurationContext(builder.Options))
        {
            dbContext.Database.EnsureCreated();
            //Modify this to suit your needs, here is an example assuming you have a table called AuthMessageSenderOption with the same fields as the class in your question
            var authMessageSender = db.Context.AuthMessageSenders.FirstOrDefault();

            // You should add some code here to check if the settings exist and provide defaults if necessary

            Data = new Dictionary<string, string>
            {
                { "PortNumber", authMessageSenderOption.PortNumber},
                { "SmtpServer", authMessageSenderOption.SmtpServer },
                { "UserName", authMessageSenderOption.UserName},
                { "Password", authMessageSenderOption.Password}
            };
        }
    }
}

最后,您需要注册自定义配置提供程序。

创建一个IConfigurationBuilder 扩展:

public static class CustomProviderExtensions
{
    public static IConfigurationBuilder AddCustomMailConfigProvider(
        this IConfigurationBuilder builder, Action<DbContextOptionsBuilder> dbOptions)
    {
        return builder.Add(new CustomMailConfigSource(dbOptions));
    }
}

使用您刚刚创建的扩展程序在您的 Main() 方法中注册提供程序:

var config = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        // Add "appsettings.json" to bootstrap EF config.
        .AddJsonFile("appsettings.json")
        // Add the EF configuration provider, which will override any
        // config made with the JSON provider.
        .AddCustomMailConfigProvider(dbOptions =>
            dbOptions .UseSqlServer(connectionStringConfig.GetConnectionString(
                "DefaultConnection"))
        )
        .Build();

参考资料:

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?tabs=basicconfiguration

https://docs.microsoft.com/en-us/dotnet/api/Microsoft.Extensions.Configuration.ConfigurationProvider?view=aspnetcore-2.0

【讨论】:

  • 这是纯艺术。
  • connectionStringConfig 是从哪里来的?
  • 我在 WebHost.CreateDefaultBuilder(args).ConfigureAppConfiguration() 内部做了这个,所以这对我有用:context.Configuration.GetConnectionString()
  • 不是最好的例子,部分代码丢失了。非退出对象出现在代码中
猜你喜欢
  • 2022-11-22
  • 2017-08-12
  • 2013-11-21
  • 2018-09-25
  • 1970-01-01
  • 1970-01-01
  • 2021-10-25
  • 2018-06-07
  • 1970-01-01
相关资源
最近更新 更多