передовая практика использования декоратора для отправки уведомлений в ядре asp - PullRequest
0 голосов
/ 22 апреля 2020

Мне нужно отправить уведомление по смс или электронной почте, и я пишу код для этого по Decorator Pattern.

, но я не знаю, пишу ли я правильно или нет, потому что мне нужно использовать несколько способов (электронная почта и смс) это не работает хорошо.

см. Код:

public abstract class Notification
{
    public abstract Task<OperationResult<string>> Send(string from, string subject, string content, string userName, string password, MailboxAddress to, int port, string smtpServer);
    public abstract Task<OperationResult<string>> Send(string lineNumber, string userApiKey, string phoneNumber, string message, string secrectKey);
}

у меня есть метод tow Send, потому что у них есть аргумент diffrent.

я реализую Notification в этом классе:

 public class SendNotification : Notification
{
    public SendNotification()
    {
    }
    /// <summary>
    /// Send Email Notifiaction
    /// </summary>
    /// <param name="from"></param>
    /// <param name="subject"></param>
    /// <param name="content"></param>
    /// <param name="userName"></param>
    /// <param name="password"></param>
    /// <param name="to"></param>
    /// <param name="port"></param>
    /// <param name="smtpServer"></param>
    /// <returns></returns>
    public override async Task<OperationResult<string>> Send(string from, string subject, string content, string userName, string password, MailboxAddress to, int port, string smtpServer)
    {
        using (var client = new SmtpClient())
        {
            var emailMessage = new MimeMessage();
            try
            {
                client.Connect(smtpServer, port, true);
                client.AuthenticationMechanisms.Remove("XOAUTH2");
                client.Authenticate(userName, password);
                emailMessage.From.Add(new MailboxAddress(from));
                emailMessage.To.Add(to);
                emailMessage.Subject = subject;
                emailMessage.Body = new TextPart(MimeKit.Text.TextFormat.Text) { Text = content };
            }
            catch (Exception ex)
            {
                return OperationResult<string>.BuildFailure(ex);
            }
            finally
            {
                await client.DisconnectAsync(true);
                client.Dispose();
            }
        }
        return OperationResult<string>.BuildSuccessResult("Success Send Email");
    }


    /// <summary>
    /// Send Sms Function
    /// </summary>
    /// <param name="lineNumber"></param>
    /// <param name="userApiKey"></param>
    /// <param name="phoneNumber"></param>
    /// <param name="message"></param>
    /// <param name="secrectKey"></param>
    /// <returns></returns>
    public override async Task<OperationResult<string>> Send(string lineNumber, string userApiKey, string phoneNumber, string message, string secrectKey)
    {
        var token = new Token().GetToken(userApiKey, secrectKey);

        var restVerificationCode = new RestVerificationCode()
        {
            Code = message,
            MobileNumber = phoneNumber
        };

        var restVerificationCodeRespone = new VerificationCode().Send(token, restVerificationCode);
        if (restVerificationCodeRespone.IsSuccessful)
        {
            return OperationResult<string>.BuildSuccessResult(restVerificationCodeRespone.Message);
        }
        return OperationResult<string>.BuildFailure(restVerificationCodeRespone.Message);
    }
}

теперь я создаю класс SendSms и класс Send Email:

E-mail:

 public class NotificationEmail : SendNotification
{
    private readonly Notification notification;

    public NotificationEmail(Notification notification) 
    {
        this.notification = notification;
    }

    public override Task<OperationResult<string>> Send(string from, string subject, string content, string userName, string password, MailboxAddress to, int port, string smtpServer)
    {
        return base.Send(from, subject, content, userName, password, to, port, smtpServer);
    }
}

SMS:

 public class NotificationSms : SendNotification
{
    private readonly Notification notification;

    public NotificationSms(Notification notification) 
    {
        this.notification = notification;
    }

    public override Task<OperationResult<string>> Send(string lineNumber, string userApiKey, string phoneNumber, string message, string secrectKey)
    {
        return base.Send(lineNumber, userApiKey, phoneNumber, message, secrectKey);
    }
}

теперь я используйте этот код в моем классе следующим образом:

SendNotification notif = new SendNotification();
NotificationSms smsSend = new NotificationSms(notif);
NotificationEmail emailSend = new NotificationEmail(smsSend);
var sendSms = await smsSend.Send(smsSetting.Result.LineNumber, smsSetting.Result.userApikey, to, content, smsSetting.Result.secretKey);
var sendEmail = await emailSend.Send(emailSetting.Result.From, "Email Confirm Code", content, emailSetting.Result.Username, emailSetting.Result.Password, to, emailSetting.Result.Port, emailSetting.Result.SmtpServer);

Теперь мне нужно использовать лучшие практики для использования декоратора. Как я могу улучшить свой код и лучший дизайн в декораторе ???

Ответы [ 2 ]

1 голос
/ 22 апреля 2020

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

Шаблон декоратора предназначен для добавления ответственности ... но вы не добавляете ответственность, вы декорируете объект с его основными функциями ... не используйте декоратор для этого.

Я бы посоветовал использовать шаблон стратегии

Некоторая документация: https://en.wikipedia.org/wiki/Strategy_pattern

TL: DR: используя композицию, вы создаете объект, используя его соответствующее поведение. Для вас я бы сказал, что вам нужен интерфейс, который абстрагирует поведение при отправке, и две реализации ... для смс и электронной почты. После сборки просто составьте объект sendnotification с помощью смс или электронной почты

0 голосов
/ 06 мая 2020

Я бы предпочел отделить конфигурацию от фактического сообщения и иметь зависимость для фактической реализации отправки. Отделение его от фактического сообщения позволяет вам создать простой интерфейс, который можно использовать для различных каналов.

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

public interface INotification
{
    Task<OperationResult<string>> Send(string subject, string message);
}

public class SmsNotfication : INotification
{
    public SmsNotfication(string lineNumber, string userApiKey, string phoneNumber, string secrectKey)
    {

    }

    public Task<OperationResult<string>> Send(string subject, string message);
    {
        var token = new Token().GetToken(userApiKey, secrectKey);

        var restVerificationCode = new RestVerificationCode()
        {
            Code = message,
            MobileNumber = phoneNumber
        };

        var restVerificationCodeRespone = new VerificationCode().Send(token, restVerificationCode);
        if (restVerificationCodeRespone.IsSuccessful)
        {
            return OperationResult<string>.BuildSuccessResult(restVerificationCodeRespone.Message);
        }
        return OperationResult<string>.BuildFailure(restVerificationCodeRespone.Message);
    }
}

public class MailNotification : INotification
{
    public MailNotification(string from, string userName, string password, MailboxAddress to, int port, string smtpServer)
    {

    }

    public Task<OperationResult<string>> Send(string message, string content)
    {
        using (var client = new SmtpClient())
        {
            var emailMessage = new MimeMessage();
            try
            {
                client.Connect(smtpServer, port, true);
                client.AuthenticationMechanisms.Remove("XOAUTH2");
                client.Authenticate(userName, password);
                emailMessage.From.Add(new MailboxAddress(from));
                emailMessage.To.Add(to);
                emailMessage.Subject = subject;
                emailMessage.Body = new TextPart(MimeKit.Text.TextFormat.Text) { Text = content };
            }
            catch (Exception ex)
            {
                return OperationResult<string>.BuildFailure(ex);
            }
            finally
            {
                await client.DisconnectAsync(true);
                client.Dispose();
            }
        }
        return OperationResult<string>.BuildSuccessResult("Success Send Email");
    }
}

public class ConsoleLoggingNotificationDecorator : INotification
{
    private readonly INotification _notification;
    public ConsoleLoggingNotificationDecorator(INotification notification) => _notification = notification;

    public Task<OperationResult<string>> Send(string message, string content)
    {
        System.Console.WriteLine("Sending message in notification channel");
        var result = _notification.Send(message, content);
        System.Console.WriteLine("Message has completed send in notification channel");
        return result;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...