メールの送信を処理する別のクラスを作成しました。私はそれを設計するために依存性注入を使っています。今、SendMessageAsync()
メソッドを使用しようとすると、SendMailCompletedイベントをチェックして、送信されたメッセージのステータスが失敗/成功したことを確認します。私はそれを実装しているクラスでどのようにイベントを実装するのか混乱しています。インターフェイスでこのイベントを言及することなく、私は注入クラスでそれをキャッチすることはできません。どのようにこれを解決するために示唆することができますか?インターフェイスにイベントがある場合のイベントの実装方法、依存関係のインジェクションでの使用方法
public interface IMailing
{
string Host { get; set; }
int Port { get; set; }
Task SendMailAsync(string toAddress, string subject, string body);
event SendCompletedEventHandler OnEmailSendComplete;
}
を次のように次のようにインターフェイスを実装しているクラスがあるように私のインターフェースが見えます -
public class Mailing : IMailing
{
private SmtpClient client = new SmtpClient();
MailMessage mm = null;
public string Host{ get; set; }
public int Port { get; set; }
// do i need this? without event being in the interface I would have had this //two following lines to manually raise the event
public event SendCompletedEventHandler OnEmailSendComplete;
public delegate void SendCompletedEventHandler(object source, AsyncCompletedEventArgs e);
// following lines were generated from the vs2017 IDE
// how do I use it when actual Send mail completed event fires?
event System.Net.Mail.SendCompletedEventHandler IMailing.OnEmailSendComplete
{
add
{
throw new NotImplementedException();
}
remove
{
throw new NotImplementedException();
}
}
public async Task SendMailAsync(string toAddress, string subject, string body)
{
mm = new MailMessage(User, toAddress, subject, body);
client.SendCompleted += Client_SendCompleted;
await client.SendMailAsync(mm).ConfigureAwait(false);
}
private void Client_SendCompleted(object sender, AsyncCompletedEventArgs e)
{
OnEmailSendComplete?.Invoke(sender, e);
}
}
さて、注入クラスは以下のようになります。これは、コンストラクタ・インジェクションを使用しています -
public class MailingInjection
{
IMailing mailing = null;
private MailingInjection()
{ }
public MailingInjection(IMailing imail)
{
mailing = imail;
}
public async Task SenMailAsync(string to, string subject, string body)
{
mailing.OnEmailSendComplete += EmailSendCompleted;
await mailing.SendMailAsync(to, subject,body).ConfigureAwait(false);
}
private void EmailSendCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
mailing.OnEmailSendComplete -= EmailSendCompleted;
}
}
できるだけコードを少なくして混乱を説明しようとしたので、このコードは実際のシナリオでは機能しませんが、私は信じている構造を持っています。私はそれを誇張しているかどうか私に教えてください。私はどんな助けにも感謝します。
あなたが意味することを記述できますか?それを実装しているクラスでイベントを実装する方法を混乱させています。インターフェイスでこのイベントを言及せずに、私は注入クラスでそれをキャッチすることはできません*あなたが実装をイベントを管理する必要はないと言っている? – Nico
私はそれを管理したいです。インプリメンテーションでは、実装されていないと言われる部分で、代理イベントをどのように配置して、注入されたクラスをキャッチできるかを示します。 – 3not3
イベントを実装するのと同じ方法で、イベントをインターフェイスに実装します。投稿したコードに基づいて、Visual Studioの "明示的にインターフェイスを実装する"オプションを使用したように見えます。これは、イベント宣言の明示的なフォームを 'add()'と 'remove()'メソッド。イベントの特別な処理を望まないなら、それをしないでください。イベントをインターフェイスで宣言するだけです。つまり、 'publicイベントSendCompletedEventHandler OnEmailSendComplete;'を呼び出すと、コンパイラは 'add()'と 'remove()'メソッドをあなたに代入させます。 –