我需要創建一個System.Net.Mail包裝器,我可以使用IOC和Fluent方式。創建郵件程序和郵件類。需要關於處置的建議
的想法是將有兩班,梅勒和郵件,使用方法如下:
IMailer mailer = new Mailer();
IMail mail = new Mail()
.Attach("Photo", fileData, "image/jpg")
.Body("This is the photo I forgot to send")
.From("[email protected]")
.Subject("The missing photo")
.To("[email protected]");
mailer.New(mail).Send();
或者全流利的方式是這樣的:
new Mailer()
.New()
.Attach("Photo", fileData, "image/jpg")
.Body("This is the photo I forgot to send")
.From("[email protected]")
.Subject("The missing photo")
.To("[email protected]")
.Done()
.Send();
我幹得最多的工作但我在處理時遇到問題。寄件人類:
public interface IMailer : IDisposable {
IMailer New(IMail mail);
IMail New();
void Cancel();
void Send();
void SendAsync(SendCompletedEventHandler callback, Object token = null);
} // IMailer
public class Mailer : IMailer {
private SmtpClient _client;
private IMail _mail;
public Mailer() {
_client = new SmtpClient();
} // Mailer
public IMailer New(IMail mail) {
_mail = mail;
return this;
} // New
public IMail New() {
_mail = new Mail(this);
return _mail;
} // New
public void Cancel() {
_client.SendAsyncCancel();
} // Cancel
public void Send() {
Send(null, null);
} // Send
public void SendAsync(SendCompletedEventHandler callback, Object token = null) {
Send(callback, token);
} // SendAsync
private void Send(SendCompletedEventHandler callback = null, Object token = null) {
using (MailMessage message = new MailMessage()) {
message.From = new MailAddress(_mail.Data.From);
message.Subject = _mail.Data.Subject;
_mail.Data.To.ForEach(x => message.To.Add(new MailAddress(x)));
message.Body = _mail.Data.Text;
_mail.Data.Attachments.ForEach(x => { message.Attachments.Add(new Attachment(new MemoryStream(x.Value.Item2), x.Key, x.Value.Item1)); });
if (callback == null)
_client.Send(message);
else {
_client.SendCompleted += callback;
_client.SendAsync(message, token);
}
};
} // Send
public void Dispose() {
Dispose(true);
} // Dispose
protected virtual void Dispose(Boolean disposing) {
if (disposing) {
if (_client != null)
_client.Dispose();
}
} // Dispose
} // Mailer
和包含郵件數據,並建立一個郵件如下郵件類:
public interface IMail {
MailData Data { get; }
IMail Attach(String name, Byte[] file, String mime);
IMail Body(String text);
IMail From(String contact);
IMail Subject(String subject);
IMail To(String contact);
IMailer Done();
} // IMail
public class Mail : IMail {
private IMailer _mailer;
public MailData Data { get; private set; }
public Mail() {
Data = new MailData();
} // Mail
public Mail(IMailer mailer) {
Data = new MailData();
_mailer = mailer;
} // Mail
public IMail Attach(String name, Byte[] file, String mime) {
Tuple<String, Byte[]> attachment;
if (!Data.Attachments.TryGetValue(name, out attachment))
Data.Attachments.Add(name, new Tuple<String, Byte[]>(mime, file));
return this;
} // Attach
public IMail Body(String text) {
Data.Text = text;
return this;
} // Body
public IMail From(String contact) {
Data.From = contact;
return this;
} // From
public IMail Subject(String subject) {
Data.Subject = subject;
return this;
} // Subject
public IMail To(String contact) {
Data.To.Add(contact);
return this;
} // To
public IMailer Done() {
return _mailer;
} // Done
} // Mail
public class MailData {
public Dictionary<String, Tuple<String, Byte[]>> Attachments { get; set; }
public String From { get; set; }
public String Subject { get; set; }
public String Text { get; set; }
public HashSet<String> To { get; set; }
public MailData() {
Attachments = new Dictionary<String, Tuple<String, Byte[]>>();
To = new HashSet<String>();
} // MailData
} // MailData
的郵件使用它是在發送電子郵件後置於MAILMESSAGE。
當我處置郵件,則SMTP客戶端也設置...
但是,我不知道如何處理郵件本身。
這對清除MailData字典中的所有附件文件非常重要。
我應該能夠做到這一點有兩種方式:
IMail mail = new Mail()
.Attach("Photo", fileData, "image/jpg")
// Define other properties of mail
// Send mail using mailer
mail.Dispose(); // Dispose mail
或完全流利時:
mailer
.New()
.Attach("Photo", fileData, "image/jpg")
// Other properties of mail
.Done()
.Send()
.Dispose();
這將處置郵件和郵件...或者:
mailer
.New()
.Attach("Photo", fileData, "image/jpg")
// Other properties of mail
.Done()
.Send()
.Clear;
這將處理與郵件相關的郵件,但不是郵件程序,所以我可以發送另一封郵件與相同的郵件河
或者您可能會建議的任何其他配置。
我不確定最好的方法去...
任何建議是值得歡迎的。
謝謝你,
米格爾
注意:使用國際奧委會的時候我會注入IMailer在我服務的......
感謝您提供有關SmtpClient和Async的提示。關於在一個使用塊中使用郵件程序是有道理的,但是我使用StructureMap將郵件程序注入到我的服務中,因此SM將在這種情況下處理這個問題......如果我要在服務中創建郵件程序,那麼它對於將其包裹成使用...這是你的意思? – 2013-03-25 22:03:40
我不知道StructureMap,但如果我認爲它與Unity相似(我熟悉),那麼您有2個選項來獲取對象實例:通過注入(到ctor或屬性)或通過解析它直接(如:var mailer = ObjectFactory.GetInstance())。在後一種情況下,您可以使用使用塊。在前一種情況下(注入),我不確定正確的方法,因爲您不僅要在完成對象時處理對象,還要確保即使發生異常時也能處理該對象。 –
Vizu
2013-03-26 08:38:04
另一個問題:請注意,我正在使用Stream填充MailMessage上的附件。這是因爲它System.Net.Mail附件不接受Byte [],這是我在我的郵件對象。我需要處理Streams嗎?我不知道是否以及如何......他們需要在場,直到發送消息。 – 2013-03-26 12:59:08