Система оповещения


Я хочу реализовать систему уведомлений почта

Уведомления.в CS

public abstract class Notification
{
    private IEmailSender emailSender;

    public string To { get; }

    public virtual string Subject { get; }

    public virtual string Template { get; }

    public virtual object Model { get; }

    public Notification(IEmailSender emailSender, string to, object model)
    {
        this.emailSender = emailSender;
        this.To = to;
        this.Model = model;
    }

    public virtual async Task SendAsync()
    {
        var engine = new RazorLightEngineBuilder()
            .UseFilesystemProject(Directory.GetCurrentDirectory())
              .UseMemoryCachingProvider()
              .Build();

        string message = await engine.CompileRenderAsync(this.Template, this.Model);

        await emailSender.SendEmailAsync(To, Subject, message);
    }
}

RegisterConfirmationNotification.в CS

public class RegisterConfirmationNotification : Notification
{
    public RegisterConfirmationNotification(IEmailSender emailSender, string to, object model)
        : base(emailSender, to, model)
    {

    }

    public override string Subject => "Account Confirmation";

    public override string Template => "Views/EmailTemplates/RegisterConfirmation.cshtml";
}

AccountController.в CS

var notification = new RegisterConfirmationNotification (emailSender, model.Email, new RegisterConfirmationViewModel { FirstName = "John" } );
await notification.SendAsync();

Моя проблема заключается в том, что у меня сложилось впечатление смешивать много вещей, которые не следует смешивать. Мой класс отвечает за сбор Razor шаблон, а также отправку почты.

Как мы может разные вещи?



580
3
задан 8 апреля 2018 в 09:04 Источник Поделиться
Комментарии
1 ответ

Как вы уже заподозрили, что ваш код пытается сделать слишком много. Разделение функциональности в собственные проблемы. (ПСП/соц -единый принцип ответственности и разделение обязанностей)

Ваш реферат Notification действует скорее как базовую модель и должна быть рефакторинг, чтобы отразить, что

public abstract class Notification {

public string To { get; }

public abstract string Subject { get; }

public abstract string Template { get; }

public virtual object Model { get; }

public Notification(string to, object model) {
this.To = to;
this.Model = model;
}
}

Класс теперь отвечает только за хранение данных, которые будут отправлены.

Это будет означать, что RegisterConfirmationNotification определение класса будет выглядеть

public class RegisterConfirmationNotification : Notification {
public RegisterConfirmationNotification(string to, object model)
: base(to, model) {

}

public override string Subject => "Account Confirmation";

public override string Template => "Views/EmailTemplates/RegisterConfirmation.cshtml";
}

SendAsync должна быть преобразована в собственную службу абстракции и реализации, а также следовать явных зависимостей принципе, принимая Notification аргумент напрямую

public interface INotificationService {
Task SendAsync(Notification notification);
}

Реализация может быть как простой, как следующие

public class NotoficationService : INotificationService {
private readonly IEmailSender emailSender;

public NotoficationService(IEmailSender emailSender) {
this.emailSender = emailSender;
}

public async Task SendAsync(Notification notification) {
var engine = new RazorLightEngineBuilder()
.UseFilesystemProject(Directory.GetCurrentDirectory())
.UseMemoryCachingProvider()
.Build();

string message = await engine.CompileRenderAsync(notification.Template, notification.Model);

await emailSender.SendEmailAsync(notification.To, notification.Subject, message);
}
}

Даже составление бритва шаблона могут быть выведены на свои услуги для того, чтобы этот код, чтобы быть более твердым. Я оставлю этот выбор для вас, чтобы реализовать.

Наконец, AccountController теперь явно зависит от INotificationService для того, чтобы иметь возможность отправлять уведомления. В Notification полученная модель может быть затем передан на обслуживание и сообщение отправлено.

public class AccountController : Controller {
private readonly INotificationService notificationService;

public AccountController(INotificationService notificationService) {
this.notificationService = notificationService;
}

//...

[HttpPost]
public async Task<IActionResult> Register([FromBody]MyModel model) {
//...

var notificationModel = new RegisterConfirmationViewModel { FirstName = "Jacques" };
var notification = new RegisterConfirmationNotification (model.Email, notificationModel);
await notificationService.SendAsync(notification);

//...

return View();
}

}

6
ответ дан 8 апреля 2018 в 04:04 Источник Поделиться