在ASP.NET Core 2.1中,我有一个类来发送使用IOptions接口的电子邮件,如下所示:
public class Email
{
private readonly ManuelaIbiEmail manuelaIbiEmail;
public Email(IOptions<ManuelaIbiEmail> manuelaIbiEmail)
{
this.manuelaIbiEmail.Username = manuelaIbiEmail.Value.Username;
this.manuelaIbiEmail.Password = manuelaIbiEmail.Value.Password;
}
public async Task SendAsync(Contato contato)
{
var smtpClient = new SmtpClient
{
Host = "smtp.sendgrid.net",
Port = 587,
EnableSsl = true,
Credentials = new NetworkCredential(manuelaIbiEmail.Username, manuelaIbiEmail.Password)
};
using (var message = new MailMessage(contato.Email, "[email protected]")
{
Subject = "Email de Manuela Ibi Nutrição Integrada",
Body = $"{contato.Comentario}\nTelefone: {contato.Telefone}"
})
{
await smtpClient.SendMailAsync(message);
}
}
}
这个类必须在控制器中实例化,例如“var whatever = new Email(???);”以便可以调用SendAsync方法。
但这里的大图是我在这个初始化中丢失了。我只是不知道在“电子邮件(某事)”中要叫什么。
只是,需要提供更多信息以便:
系统应该从Secrets读取用户名,密码,因此我在Startup.cs中有以下行:
services.Configure<ManuelaIbiEmail>(Configuration.GetSection("ManuelaIbiEmail"));
ManuelaIbiEmail是一个非常简单的POCO类:
public class ManuelaIbiEmail
{
public string Username { get; set; }
public string Password { get; set; }
}
控制器看起来像:
public class ContactController : Controller
{
private readonly ManuelaIbiEmail manuelaIbiEmail;
public IActionResult Contact()
{
return View(new Contato());
}
[HttpPost]
public async Task<IActionResult> ContactAsync(Contato contato)
{
var email = new Email();
email.SendAsync(contato);
return Ok();
}
}
如果有人能够善意地告诉我我错过了什么,我会很感激。
先感谢您
依赖注入的全部意义不是那样做。
您可以通过属性在方法中注入它:
public class ContactController : Controller
{
public IActionResult Contact()
{
return View(new Contato());
}
[HttpPost]
public async Task<IActionResult> ContactAsync(Contato contato, [FromServices]Email email)
{
email.SendAsync(contato);
return Ok();
}
}
或者通过构造函数注入:
public class ContactController : Controller
{
private readonly EMail email;
public ContactController(Email email)
{
this.email = email;
}
public IActionResult Contact()
{
return View(new Contato());
}
[HttpPost]
public async Task<IActionResult> ContactAsync(Contato contato)
{
email.SendAsync(contato);
return Ok();
}
}
只需通过构造函数注入Email
:
public class ContactController : Controller
{
public ContactController(Email email)
{
Email = email;
}
public Email Email { get; }
public IActionResult Contact()
{
return View(new Contato());
}
[HttpPost]
public async Task<IActionResult> ContactAsync(Contato contato)
{
Email.SendAsync(contato);
return Ok();
}
}
理想情况下,您不希望通过手动初始化Email
将控制器与实现问题紧密耦合,因为类应取决于抽象而非结果。
摘要电子邮件类
public interface IEmail {
Task SendAsync(Contato contato);
}
public class Email: IEmail {
//...omitted for brevity
}
你可以通过构造函数注入将它注入控制器
public class ContactController : Controller {
private readonly IEmail email;
public ContactController(IEmail email) {
this.email = email;
}
public IActionResult Contact() {
return View(new Contato());
}
[HttpPost]
public async Task<IActionResult> ContactAsync(Contato contato) {
await email.SendAsync(contato);
return Ok();
}
}
配置正确后
services.AddTransient<IEmail, Email>();
容器将在创建注入对象图时解析所有依赖项。
我的主张:
Create一个IOption
实例并使用此实例初始化您的类Email
using Microsoft.Extensions.Options;
var mail = new ManuelaIbiEmail() { Username= "", Password="" };
IOptions<ManuelaIbiEmail> options = Options.Create(mail);
var email = new Email(options);