开发者

Email Provider Design

I was thinking of creating an email provider using the provider pattern. Our Email system is in disarray. We have differ开发者_如何学Goent areas in the same app as well as different apps using their own way of handling email. I would like to create an email provider because the information across the board is roughly the same. By using the provider pattern I can have our default way of handling email but also by using an interface I can have more specific/custom email handling introduced.

So I'm not quite sure how I would setup the interface to handle each areas specific/custom handling and was looking for some guidance. I would have my abstract class to house default settings/functionality then have my email provider which would execute call to sproc to send email.

Now not sure how I would introduce a new interface so that if another dev needed to do some customization pertaining to the area hes working on he could the extend the provider to handle his changes. Any ideas on this approach or maybe suggest other approaches? If you like the provider approach and know how to implement what I'm suggesting a bit of pseudo code would be nice. :)

public Interface IEmail   

abstract class EmailProviderBase : ProviderBase, IEmail

   //Default settings and methods
   public virtual SendEmail(){}


//Used to handle default implementation
public class EmailProvider : EmailProviderBase

//But want other classes to be used to handle other devs custom implementations
//I guess I could create another provider per say based on EmailProviderBase.
public class CustomEmail : EmailProviderBase

Can anyone tell me if they like this approach or not? Also if not, how would you design it using interfaces?

Thanks, DND


This may be just me, but it seems to me the System.Net.Mail classes already do a good job of abstracting the details and strike a good balance between customizability and ease of use. If you attempt to simplify much more, you'll lose the ability to customize when you need to.

We started to do something along this path with emails and as we did more projects, and our needs changed, we ended up having to customize our classes to the point where it became apparent that the entire exercise was a waste of time.

However, I understand where you're coming from, and here's another possibility for unifying how you send emails from your apps. It's not what you asked for, but presented as a possible different way of approaching the problem, based on what worked for our team.

What we settled on was based SOLELY on our biggest pain point, which was that our administrators would swap out the Exchange server every few years, OR they would change the IP address for some reason or another. Every time this happened, we'd have to go recompile a bunch of code, which was pretty frustrating.

We ended up setting up a web service that has email functions. Now, all of our emails in our internal apps use the web service. When our Admins change something on the server, we only need to adjust just the .config file in our web service and don't have to re-compileor edit the .config in every app that sends emails.

This worked especially well for us, because we were able to integrate error handling to our central error logging database, so all of our apps have just a couple of lines of code to send an email. Error handling is included free of charge.

The only adjustment we've had to make since we implemented this was to have the web service send emails via the PickupDirectory instead of communicating directly with the Exchange server. This allows the service to work when the Exchange server is down (maintenance, rebooting to apply patches, etc.)

The code in the web service is fairly straightforward as well, and handles sanitation using the Microsoft.Security.AntiXss component.

The references to the Overseer system in code are references to our central error logging database. I'm not going to include that code as this is already WAY too long an answer, and all it really does is log errors to a SQL database.

Sorry it's in VB where you specified C#, but if you're interested, it should be very easy to convert.

<WebMethod()> _
 Public Function SendEmailViaPickupDir(ByVal FromAddress As String, ByVal ToList As String, ByVal CcList As String, ByVal BccList As String, _
                    ByVal Subject As String, ByVal MessageBody As String, ByVal IsBodyHtml As Boolean) As Boolean

    Dim msg As System.Net.Mail.MailMessage = BuildMessage(FromAddress, ToList, CcList, BccList, Subject, MessageBody, IsBodyHtml)

    If Not msg Is Nothing Then
        Return SendMessageViaPickupDir(msg)
    Else
        Return False
    End If

End Function

Private Function BuildMessage(ByVal FromAddress As String, ByVal ToList As String, ByVal CcList As String, ByVal BccList As String, _
     ByVal Subject As String, ByVal MessageBody As String, ByVal IsBodyHtml As Boolean) As System.Net.Mail.MailMessage

    Dim msg As New System.Net.Mail.MailMessage

    Try
        msg.From = New System.Net.Mail.MailAddress(FromAddress)

        If Not ToList Is Nothing Then
            For Each Address As String In ToList.Split(";".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)
                msg.To.Add(New System.Net.Mail.MailAddress(Address.Trim()))
            Next
        End If

        If Not CcList Is Nothing Then
            For Each Address As String In CcList.Split(";".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)
                msg.CC.Add(New System.Net.Mail.MailAddress(Address.Trim()))
            Next

        End If
        If Not BccList Is Nothing Then
            For Each Address As String In BccList.Split(";".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)
                msg.Bcc.Add(New System.Net.Mail.MailAddress(Address.Trim()))
            Next

        End If

        msg.Subject = Microsoft.Security.Application.AntiXss.HtmlEncode(Subject)
        If (IsBodyHtml) Then
            msg.Body = Microsoft.Security.Application.AntiXss.GetSafeHtmlFragment(MessageBody)
        Else
            ' This was causing formatting issues...
            msg.Body = MessageBody
        End If
        msg.IsBodyHtml = IsBodyHtml

    Catch ex As Exception
        Dim s As New OverseerService
    s.WriteToSql(Convert.ToInt64(ConfigurationManager.AppSettings("OverseerWebSiteResourceid")), User.Identity.Name, _
     My.Computer.Name, ex.ToString(), MyCompany.Overseer.EventLogger.SeverityLevel.Critical)
        Return Nothing
    End Try

    Return msg

End Function

Private Function SendMessageViaPickupDir(ByVal msg As System.Net.Mail.MailMessage) As Boolean
    Dim ret As Boolean = False

    Try
        ' try to send through pickup dir
        Dim c1 As New System.Net.Mail.SmtpClient("localhost")
        c1.DeliveryMethod = Net.Mail.SmtpDeliveryMethod.PickupDirectoryFromIis
        c1.Send(msg)
        ret = True

    Catch ex As Exception
        Try
            ' log as a known error
            Dim s As New OverseerService
            s.WriteToSql(Convert.ToInt64(ConfigurationManager.AppSettings("OverseerWebSiteResourceid")), User.Identity.Name, _
             My.Computer.Name, "failed to write email to pickup dir " + ex.ToString(), MyCompany.Overseer.EventLogger.SeverityLevel.KnownError)
        Catch
            ' ignore error from writing the error
        End Try
    End Try

    Return ret

End Function


Have you checked out http://mailsystem.codeplex.com/? That's probably the most elaborate of the OSS email utilities on codeplex. There's a much more simple product on codeplex that is more akin to what you described above, but I'm not having any luck finding it right now.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜