EDN Admin
Well-known member
Hello,
I need to create an System.Net.Mail wrapper that I could use with IOC and in a Fluent way.
The idea would be to have two classes, Mailer and Mail, used as follows:IMailer mailer = new Mailer();
IMail mail = new Mail()
.Attach("Photo", fileData, "image/jpg")
.Body("This is the photo I forgot to send")
.From("from@xyz.com")
.Subject("The missing photo")
.To("to@xyz.com");
mailer.New(mail).Send();
Or in a completely Fluent way something like:new Mailer()
.New()
.Attach("Photo", fileData, "image/jpg")
.Body("This is the photo I forgot to send")
.From("from@xyz.com")
.Subject("The missing photo")
.To("to@xyz.com")
.Done()
.Send();
I have done most of the work but I am having a problems with disposing. The mailer class:
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
And the mail class which contains the mail data and builds a mail is as follows: 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
The mailer uses a MailMessage which is disposed just after sending the email.
When I dispose the mailer then the SMTP Client is also disposed ...
However, I am not sure how to dispose the Mail itself.
This would be important to clear all those Attachements Files in the MailData dictionary.
I should be able to do it in two ways:IMail mail = new Mail()
.Attach("Photo", fileData, "image/jpg")
// Define other properties of mail
// Send mail using mailer
mail.Dispose(); // Dispose mail
Or when completely fluently:mailer
.New()
.Attach("Photo", fileData, "image/jpg")
// Other properties of mail
.Done()
.Send()
.Dispose();
This would dispose the mailer and its mail ... Or:mailer
.New()
.Attach("Photo", fileData, "image/jpg")
// Other properties of mail
.Done()
.Send()
.Clear;
This would dispose the Mail associated to the mailer but not the mailer so I can send another mail with the same mailer.
Or any other configuration that you might suggest.
I am not sure the best way to go ...
Any advice is welcome.
Thank You,
Miguel
NOTE: when using IOC I will inject the IMailer in my services ...
View the full article
I need to create an System.Net.Mail wrapper that I could use with IOC and in a Fluent way.
The idea would be to have two classes, Mailer and Mail, used as follows:IMailer mailer = new Mailer();
IMail mail = new Mail()
.Attach("Photo", fileData, "image/jpg")
.Body("This is the photo I forgot to send")
.From("from@xyz.com")
.Subject("The missing photo")
.To("to@xyz.com");
mailer.New(mail).Send();
Or in a completely Fluent way something like:new Mailer()
.New()
.Attach("Photo", fileData, "image/jpg")
.Body("This is the photo I forgot to send")
.From("from@xyz.com")
.Subject("The missing photo")
.To("to@xyz.com")
.Done()
.Send();
I have done most of the work but I am having a problems with disposing. The mailer class:
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
And the mail class which contains the mail data and builds a mail is as follows: 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();
public Mail(IMailer mailer) {
Data = new MailData();
_mailer = mailer;
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
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
The mailer uses a MailMessage which is disposed just after sending the email.
When I dispose the mailer then the SMTP Client is also disposed ...
However, I am not sure how to dispose the Mail itself.
This would be important to clear all those Attachements Files in the MailData dictionary.
I should be able to do it in two ways:IMail mail = new Mail()
.Attach("Photo", fileData, "image/jpg")
// Define other properties of mail
// Send mail using mailer
mail.Dispose(); // Dispose mail
Or when completely fluently:mailer
.New()
.Attach("Photo", fileData, "image/jpg")
// Other properties of mail
.Done()
.Send()
.Dispose();
This would dispose the mailer and its mail ... Or:mailer
.New()
.Attach("Photo", fileData, "image/jpg")
// Other properties of mail
.Done()
.Send()
.Clear;
This would dispose the Mail associated to the mailer but not the mailer so I can send another mail with the same mailer.
Or any other configuration that you might suggest.
I am not sure the best way to go ...
Any advice is welcome.
Thank You,
Miguel
NOTE: when using IOC I will inject the IMailer in my services ...
View the full article