Mic*_*ida 6 c# dependency-injection asp.net-core-3.1
我正在尝试将 appsettings.json 中的几个电子邮件帐户注入到电子邮件服务中。
编辑:我也EmailRepository.cs
需要注射。DbContext
我使用了 @Nkosi 的答案,它无需 DbContext 即可工作。我计划DbContextPool
在生产中使用,那么如何在我的方法中取出其中之一呢ConfigureServices
?
应用程序设置.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"
}
]
Run Code Online (Sandbox Code Playgroud)
SanSender.cs:
"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"
}
]
Run Code Online (Sandbox Code Playgroud)
电子邮件存储库.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();
}
}
Run Code Online (Sandbox Code Playgroud)
启动.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;
}
}
Run Code Online (Sandbox Code Playgroud)
控制器:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<List<SanSender>>((settings) =>
{
Configuration.GetSection("SanSenders").Bind(settings);
});
services.AddScoped<EmailRepository>();
services.AddControllersWithViews();
}
Run Code Online (Sandbox Code Playgroud)
在我添加的控制器中IOptions<List<SanSender>> optionsSanSenders
,我可以在那里访问它们,但EmailService.cs
在类库中,我宁愿不添加不必要的依赖项。
EmailService 确实有IEnumerable<SanSender> SanSenders
,但它的长度/计数为零。
我究竟做错了什么?
改变方法。
public class SanSenderOptions {
public List<SanSender> SanSenders { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
从配置中提取设置,然后在需要的地方注册它们
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();
}
Run Code Online (Sandbox Code Playgroud)
存储库将使注入的发件人得到解析。
应重构控制器以获得配置的选项。
public class HomeController : Controller {
public HomeController(IOptions<SanSenderOptions>> optionsSanSenders,
EmailRepository emailService) {
var senders = options.Value.SanSenders; //<--
}
public IActionResult Index() {
return View();
}
}
Run Code Online (Sandbox Code Playgroud)
ASP.NET Core 中的参考配置