ASP.NET Core 3.1将来自appsettings.json的对象数组注入注入的服务 [英] ASP.NET Core 3.1 injecting array of objects from appsettings.json into an injected service

查看:0
本文介绍了ASP.NET Core 3.1将来自appsettings.json的对象数组注入注入的服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将appsettings.json中的几个电子邮件帐户注入电子邮件服务。

编辑:我的EmailRepository.cs也需要注入DbContext。我使用了@Nkosi的答案,它在不需要DbContext的情况下起作用。我计划在生产中使用DbContextPool,那么如何在我的ConfigureServices方法中提取其中一个?

appsettings.json:

"SanSenders": [
  {
    "Host": "mail.theFourSeasons.com",
    "FromName": "The Four Seasons",
    "IsNoReply": true,
    "IsSssl": true,
    "Password": "tooGoodToBeTrue",
    "Port": 465,
    "Username": "noreply@theFourSeasons.com"
  },

  {
    "Host": "mail.theFourSeasons.com",
    "FromName": "Franki",
    "IsNoReply": false,
    "IsSssl": true,
    "Password": "cantTakeMyEyesOffYou",
    "Port": 465,
    "Username": "franki@theFourSeasons.com"
  }
]

SanSender.cs:

public class SanSender
{
    public string FromName { get; set; }
    public string Host { get; set; }
    public bool IsNoReply { get; set; }
    public bool IsSsl { get; set; }
    public string Password { get; set; }
    public int Port { get; set; }
    public string Username { get; set; }

    public async Task<bool> SendEmailAsync(
        string toAddress, string subject, string htmlMessage)
    {
        throw new NotImplementedException();
    }
}

EmailRepository.cs:

public class EmailRepository
{
    public IEnumerable<SanSender> SanSenders { get; set; }

    //Edit: I need a DbContext injected as well.
    public EmailRepository(ApplicationDbContext applicationDbContext,  
        IEnumerable<SanSender> sanSenders)
    {
         SanSenders = sanSenders;
    }
}

Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<List<SanSender>>((settings) =>
    {
        Configuration.GetSection("SanSenders").Bind(settings);
    });

    services.AddScoped<EmailRepository>();

    services.AddControllersWithViews();
}

控制器:

public class HomeController : Controller
{
    public HomeController(
        IOptions<List<SanSender>> optionsSanSenders, EmailRepository emailService)
    {
    }

    public IActionResult Index()
    {
        return View();
    }
}

我在控制器中添加了IOptions<List<SanSender>> optionsSanSenders,我可以在那里访问它们,但EmailService.cs在类库中,我不希望向它添加不必要的依赖项。

EmailService确实有IEnumerable<SanSender> SanSenders,但其长度/计数为零。

我做错了什么?

推荐答案

更改方法。

public class SanSenderOptions {
     public List<SanSender> SanSenders { get; set; }
}

从配置中提取设置,然后在需要的地方注册它们

public void ConfigureServices(IServiceCollection services) {
    SanSender[] senders = Configuration.GetSection("SanSenders").Get<SanSender[]>();

    services.Configure<SanSenderOptions>(options => {
        options.SanSenders = senders.ToList();
    });

    services.AddScoped<EmailRepository>(sp => 
        new EmailRepository(sp.GetRequiredService<ApplicationDbContext>(), senders));

    services.AddControllersWithViews();
}

存储库将解析注入的发件人。

应重构控制器以获得配置的选项。

public class HomeController : Controller {
    public HomeController(IOptions<SanSenderOptions>> optionsSanSenders, 
          EmailRepository emailService) {
        var senders = options.Value.SanSenders; //<--
    }

    public IActionResult Index() {
        return View();
    }

}

引用Configuration in ASP.NET Core

引用Options pattern in ASP.NET Core

这篇关于ASP.NET Core 3.1将来自appsettings.json的对象数组注入注入的服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆