2011-09-23 148 views
3

我正在考慮使用提供商模式創建電子郵件提供商。我們的電子郵件系統處於混亂狀態。我們在同一個應用程序以及不同的應用程序中使用自己的處理電子郵件的方式有不同的區域。我想創建一個電子郵件提供商,因爲全線的信息大致相同。通過使用提供者模式,我可以使用我們的默認處理電子郵件的方式,但也可以使用接口,我可以引入更多特定/自定義電子郵件處理。電子郵件提供商設計

所以我不太清楚我將如何設置界面來處理每個區域特定/自定義處理,並正在尋找一些指導。我希望我的抽象類能夠容納默認設置/功能,然後讓我的電子郵件提供商執行對sproc的調用以發送電子郵件。

現在不知道我將如何引入一個新界面,以便如果另一個開發人員需要執行與他正在開發的區域有關的一些定製,他可以擴展提供程序以處理其更改。這種方法的任何想法或可能建議其他方法?如果你喜歡提供者的方法,並知道如何實現我所建議的一些僞代碼會很好。 :)

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 

有誰能告訴我他們是否喜歡這種方法?如果不是,你將如何使用接口來設計它?

感謝, DND

回答

2

這可能只是我,但在我看來,System.Net.Mail類已經這樣做了抽象的細節一個良好的工作和罷工的可定製性和易用性之間的良好平衡。如果您嘗試簡化更多,您將失去在需要時自定義的能力。

我們開始沿着這條道路做電子郵件,當我們做了更多的項目,並且我們的需求改變了,我們最終不得不定製我們的班級,以至於顯然整個練習是浪費時間。

但是,我知道你來自哪裏,這裏有另一種統一如何從應用程序發送電子郵件的可能性。這不是你要求的,而是根據我們團隊的工作原理,以一種可能的不同方式來處理問題。

我們的決定基於SOLELY對我們最大的痛點,那就是我們的管理員每隔幾年就會換出Exchange服務器,或者他們會因爲某種原因更改IP地址。每次發生這種情況時,我們都必須重新編譯一堆代碼,這非常令人沮喪。

我們最終設置了一個具有電子郵件功能的Web服務。現在,我們內部應用中的所有電子郵件都使用Web服務。當我們的管理員更改服務器上的某些內容時,我們只需要調整Web服務中的.config文件,而不必在每個發送電子郵件的應用程序中重新編譯或編輯.config。

這對我們特別有效,因爲我們能夠將錯誤處理集成到我們的中央錯誤記錄數據庫中,所以我們所有的應用程序都只有幾行代碼來發送電子郵件。錯誤處理是免費的。

自從我們實現這個以來,唯一必須做的調整是讓Web服務通過PickupDirectory發送電子郵件,而不是直接與Exchange服務器通信。這允許服務在Exchange服務器關閉時進行工作(維護,重新啓動以應用修補程序等)。)

Web服務中的代碼也相當簡單,並使用Microsoft.Security.AntiXss組件處理衛生。

代碼中對監督系統的引用是對我們的中央錯誤記錄數據庫的引用。我不打算包含該代碼,因爲這已經太長了答案,而且它確實會將錯誤記錄到SQL數據庫。

對不起,它是在你指定C#的VB中,但如果你有興趣,它應該很容易轉換。

<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 
+1

戴夫 - 我喜歡這個想法使用的Web服務。我想如果我通過數據庫發送電子郵件,我可以實現更靈活的架構設計。我也可以將我的電子郵件提供商設計也納入其中。你怎麼看? – DotNetDude

+1

您可能可以通過電子郵件發送數據庫。我不知道這是否會是更好的選擇。我必須嘗試調查。我們幾乎堅持這種設計,因爲它消除了我們所有的痛苦,並且對我們來說工作得非常好,但是如果您想進一步改進它,那麼您會獲得更多的權力! – David

+0

好的感謝您的回覆! – DotNetDude

1

你簽出了http://mailsystem.codeplex.com/?這可能是codeplex上最複雜的OSS電子郵件工具。在codeplex上有一個更簡單的產品,更類似於上面所描述的,但我現在沒有任何運氣可以找到它。

+0

聽起來很有趣。將進一步研究。感謝回覆! – DotNetDude

相關問題