Fixing an issue with output parameters that are of type IntPtr
[castle.git] / Components / EmailSender / Castle.Components.Common.EmailSender / Smtp / SmtpSender.cs
blob18deb36326774fbab0ce96c51ece64ac9eddb71c
1 // Copyright 2004-2008 Castle Project - http://www.castleproject.org/
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle.Components.Common.EmailSender.Smtp
17 using System;
18 using System.Collections;
19 using System.ComponentModel;
20 using System.IO;
21 using System.Net;
22 using System.Net.Mail;
24 /// <summary>
25 /// Uses Smtp to send emails.
26 /// </summary>
27 public class SmtpSender : IEmailSender
29 private SmtpClient smtpClient;
30 private bool asyncSend = false;
31 private bool configured;
32 private string hostname;
33 private int port = 25;
34 private NetworkCredential credentials = new NetworkCredential();
36 /// <summary>
37 /// This service implementation
38 /// requires a host name in order to work
39 /// </summary>
40 /// <param name="hostname">The smtp server name</param>
41 public SmtpSender(string hostname)
43 this.hostname = hostname;
45 smtpClient = new SmtpClient(hostname);
48 /// <summary>
49 /// Gets or sets the port used to
50 /// access the SMTP server
51 /// </summary>
52 public int Port
54 get { return port; }
55 set { port = value; }
58 /// <summary>
59 /// Gets the hostname.
60 /// </summary>
61 /// <value>The hostname.</value>
62 public string Hostname
64 get { return hostname; }
67 /// <summary>
68 /// Gets or sets a value which is used to
69 /// configure if emails are going to be sent asyncrhonously or not.
70 /// </summary>
71 public bool AsyncSend
73 get { return asyncSend; }
74 set { asyncSend = value; }
77 /// <summary>
78 /// Gets or sets a value that specifies
79 /// the amount of time after which a synchronous Send call times out.
80 /// </summary>
81 public int Timeout
83 get { return smtpClient.Timeout; }
84 set { smtpClient.Timeout = value; }
87 /// <summary>
88 /// Sends a message.
89 /// </summary>
90 /// <exception cref="ArgumentNullException">If any of the parameters is null</exception>
91 /// <param name="from">From field</param>
92 /// <param name="to">To field</param>
93 /// <param name="subject">e-mail's subject</param>
94 /// <param name="messageText">message's body</param>
95 public void Send(String from, String to, String subject, String messageText)
97 if (from == null) throw new ArgumentNullException("from");
98 if (to == null) throw new ArgumentNullException("to");
99 if (subject == null) throw new ArgumentNullException("subject");
100 if (messageText == null) throw new ArgumentNullException("messageText");
102 Send(new Message(from, to, subject, messageText));
105 /// <summary>
106 /// Sends a message.
107 /// </summary>
108 /// <exception cref="ArgumentNullException">If the message is null</exception>
109 /// <param name="message">Message instance</param>
110 public void Send(Message message)
112 if (message == null) throw new ArgumentNullException("message");
114 ConfigureSender(message);
116 if (asyncSend)
118 // The MailMessage must be diposed after sending the email.
119 // The code creates a delegate for deleting the mail and adds
120 // it to the smtpClient.
121 // After the mail is sent, the message is disposed and the
122 // eventHandler removed from the smtpClient.
123 MailMessage msg = CreateMailMessage(message);
124 Guid msgGuid = new Guid();
125 SendCompletedEventHandler sceh = null;
126 sceh = delegate(object sender, AsyncCompletedEventArgs e)
128 if (msgGuid == (Guid)e.UserState)
129 msg.Dispose();
130 // The handler itself, cannot be null, test omitted
131 smtpClient.SendCompleted -= sceh;
133 smtpClient.SendCompleted += sceh;
134 smtpClient.SendAsync(msg, msgGuid);
136 else
138 using (MailMessage msg = CreateMailMessage(message))
140 smtpClient.Send(msg);
145 public void Send(Message[] messages)
147 foreach (Message message in messages)
149 Send(message);
153 /// <summary>
154 /// Converts a message from Castle.Components.Common.EmailSender.Message type
155 /// to System.Web.Mail.MailMessage
156 /// </summary>
157 /// <param name="message">The message to convert.</param>
158 /// <returns>The converted message .</returns>
159 private MailMessage CreateMailMessage(Message message)
161 MailMessage mailMessage = new MailMessage(message.From, message.To.Replace(';', ','));
163 if (!String.IsNullOrEmpty(message.Cc))
165 mailMessage.CC.Add(message.Cc);
168 if (!String.IsNullOrEmpty(message.Bcc))
170 mailMessage.Bcc.Add(message.Bcc);
173 mailMessage.Subject = message.Subject;
174 mailMessage.Body = message.Body;
175 mailMessage.BodyEncoding = message.Encoding;
176 mailMessage.IsBodyHtml = (message.Format == Format.Html);
177 mailMessage.Priority = (MailPriority)Enum.Parse(typeof(MailPriority), message.Priority.ToString());
179 foreach (DictionaryEntry entry in message.Headers)
181 mailMessage.Headers.Add((string)entry.Key, (string)entry.Value);
184 foreach (MessageAttachment attachment in message.Attachments)
186 Attachment mailAttach;
188 if (attachment.Stream != null)
190 mailAttach = new Attachment(attachment.Stream, attachment.MediaType);
192 else
194 mailAttach = new Attachment(attachment.FileName, attachment.MediaType);
197 mailMessage.Attachments.Add(mailAttach);
200 if (message.Resources != null && message.Resources.Count > 0)
202 AlternateView htmlView = AlternateView.CreateAlternateViewFromString(message.Body, message.Encoding, "text/html");
203 foreach (string id in message.Resources.Keys)
205 LinkedResource r = message.Resources[id];
206 r.ContentId = id;
207 if (r.ContentStream != null)
209 htmlView.LinkedResources.Add(r);
212 mailMessage.AlternateViews.Add(htmlView);
214 return mailMessage;
218 /// <summary>
219 /// Gets or sets the domain.
220 /// </summary>
221 /// <value>The domain.</value>
222 public String Domain
224 get { return credentials.Domain; }
225 set { credentials.Domain = value; }
228 /// <summary>
229 /// Gets or sets the name of the user.
230 /// </summary>
231 /// <value>The name of the user.</value>
232 public String UserName
234 get { return credentials.UserName; }
235 set { credentials.UserName = value; }
238 /// <summary>
239 /// Gets or sets the password.
240 /// </summary>
241 /// <value>The password.</value>
242 public String Password
244 get { return credentials.Password; }
245 set { credentials.Password = value; }
248 /// <summary>
249 /// Configures the message or the sender
250 /// with port information and eventual credential
251 /// informed
252 /// </summary>
253 /// <param name="message">Message instance</param>
254 private void ConfigureSender(Message message)
256 if (!configured)
258 if (HasCredentials)
260 smtpClient.Credentials = credentials;
263 smtpClient.Port = port;
265 configured = true;
269 /// <summary>
270 /// Gets a value indicating whether credentials were informed.
271 /// </summary>
272 /// <value>
273 /// <see langword="true"/> if this instance has credentials; otherwise, <see langword="false"/>.
274 /// </value>
275 private bool HasCredentials
277 get { return credentials.UserName != null && credentials.Password != null ? true : false; }