使用IOption的类的实例化

时间:2018-09-04 12:45:18

标签: c# asp.net-mvc asp.net-core dependency-injection

在ASP.NET Core 2.1中,我有一个使用IOptions接口发送电子邮件的类,如下所示:

(A.T*B).T

此类必须在控制器中使用“ var what = new Email(???);”这样的行实例化。以便可以调用SendAsync方法。

但是这里的大局是我在初始化中迷路了。我只是不知道在“ Email( something )”中叫什么。

只需提供一些更多信息,以防万一:

系统应从Secrets中读取用户名和密码,因此Startup.cs中包含以下行:

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, "manuelaibi66@gmail.com")
        {
            Subject = "Email de Manuela Ibi Nutrição Integrada",
            Body = $"{contato.Comentario}\nTelefone: {contato.Telefone}"
        })
        {
            await smtpClient.SendMailAsync(message);
        }
    }
}

ManuelaIbiEmail是一个非常简单的POCO类:

services.Configure<ManuelaIbiEmail>(Configuration.GetSection("ManuelaIbiEmail"));

控制器看起来像:

public class ManuelaIbiEmail
{
    public string Username { get; set; }
    public string Password { get; set; }
}

如果任何人都可以友好地告诉我我所缺少的东西,我将不胜感激。

提前谢谢

4 个答案:

答案 0 :(得分:4)

依赖注入的全部目的是不这样做

您可以通过属性通过方法将其注入:

myAajax ();
document.fonts.ready.then(function () {$("#ajaxContent").show(); });

或通过构造函数注入:

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();
    }
}

答案 1 :(得分:1)

理想情况下,您不希望通过手动初始化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>();

容器将在创建用于注入的对象图时解析所有依赖项。

答案 2 :(得分:1)

只需通过构造函数注入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();
    }
}

答案 3 :(得分:-2)

我的主张:

Create一个IOption实例,并使用该实例初始化您的类Email

using Microsoft.Extensions.Options;

var mail = new ManuelaIbiEmail() { Username= "", Password="" };
IOptions<ManuelaIbiEmail> options = Options.Create(mail);
var email = new Email(options);