Создание класса, использующего IOption - PullRequest
0 голосов
/ 04 сентября 2018

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

Этот класс должен быть создан в контроллере с помощью строки типа "var what = new Email (???);" для того, чтобы метод SendAsync мог быть вызван.

Но общая картина в том, что я потерян в этой инициализации. Я просто не знаю, что позвонить в «Email ( что-то )».

Просто, предоставив немного больше информации на случай необходимости:

Система должна прочитать имя пользователя, пароль из 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();
    }
}

Если кто-то может быть настолько любезен, чтобы сказать мне, что мне не хватает, я буду признателен.

Заранее спасибо

Ответы [ 4 ]

0 голосов
/ 04 сентября 2018

Просто введите 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();
    }
}
0 голосов
/ 04 сентября 2018

Весь смысл внедрения зависимости состоит в том, чтобы не делал этого .

Вы можете добавить его в метод через атрибуты:

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();
    }
}
0 голосов
/ 04 сентября 2018

Мое предложение:

Создайте IOption экземпляр и инициируйте ваш класс Email с этим экземпляром

using Microsoft.Extensions.Options;

var mail = new ManuelaIbiEmail() { Username= "", Password="" };
IOptions<ManuelaIbiEmail> options = Options.Create(mail);
var email = new Email(options);
0 голосов
/ 04 сентября 2018

В идеале вы не хотите тесно связывать свой контроллер с проблемами реализации, вручную инициализируя 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>();

контейнер разрешит все зависимости при создании графа объекта для внедрения.

...