2015-06-21 65 views
1

我有以下情形,我調用一個方法在我的數據訪問代碼從我的業務層:在DALtry catch塊位置

//Call the method from BL 
SqlHandler sh = new SqlHandler(); 
var names = sh.GetNames(); 

方法例如:

public IEnumerable<string> GetNames() 
{ 
    string conString = GetOpenConnection(); 
    using (SqlConnection connection = new SqlConnection(conString)) 
    { 
     connection.Open(); 
     using(SqlCommand cmd = new SqlCommand("SELECT Name From Names")) 
     { 
      //... 
     } 
    } 
} 

我需要是記錄我的DAL中發生的任何異常,並使用適當的消息向用戶顯示消息。據我可以看到我有下列選項:

1)僅包圍BL呼叫和記錄和顯示從那裏消息:

try 
{ 
    SqlHandler sh = new SqlHandler(); 
    var names = sh.GetNames(); 
} 
catch (Exception ex) 
{ 
    ex.LogException(); 
    MessageBox.Show(ex.Message); 
} 

2)環繞兩個呼叫,分裂記錄部分和通知部分分成2個部分:

try 
{ 
    SqlHandler sh = new SqlHandler(); 
    var names = sh.GetNames(); 
} 
catch (Exception ex) 
{ 
    MessageBox.Show(ex.Message); 
} 

public IEnumerable<string> GetNames() 
{ 
    try 
    { 
     string conString = GetOpenConnection(); 
     using (SqlConnection connection = new SqlConnection(conString)) 
     { 
      connection.Open(); 
      using (SqlCommand cmd = new SqlCommand("SELECT Name From Names")) 
      { 
       //... 
      } 
     } 
    } 
    catch (Exception ex) 
    { 
     ex.LogException(); 
     //propagate the exception to the caller 
     throw; 
    } 
} 

3)當然,我可能失去了一些東西,我會很樂意瞭解

什麼是首選Appro公司在這裏的應用程序架構方面?前兩者之間是否有功能差異?

+2

這是基於意見的.. –

+0

是你的問題「我應該把try {} catch {}'塊放到DAL或BAL中嗎? – hdoghmen

+0

選項1看起來不錯...您可能需要像http://stackoverflow.com/a/136092/747609這樣的東西來處理不同的事情。儘管如此,這可能會很麻煩。 – IROEGBU

回答

2

我建議第三個選項:把錯誤記錄和錯誤顯示在UI層。

在您的用戶界面中註冊一個central error handler。在那裏,你可以

  • 顯示錯誤(無論是簡單的MessageBox或用「更多細節」看中窗口和按鈕「以開發報告」)和

  • 日誌一切,

不必雜亂帶有全部try-catch子句的BL方法。

這有很多優點:

  • 它會使你的BL代碼更易於閱讀。
  • 你不能忘記一個BL方法。
  • 更容易對錯誤處理代碼進行(集中式)更改。
  • 您不會將您的業務邏輯與特定類型的用戶界面耦合在一起,這對用戶界面有很多好處:例如,您可以稍後在基於Web的項目中重用它,並且可以測試您的業務邏輯與單元測試
+0

然而,這是一個有趣的方法,如果在調用異常傾向方法後,我怎麼能知道它是否成功(_i.e_我應該重試調用還是停止執行其餘代碼並返回)? – Yoav

+0

@Yoav:* Ususally *,異常是您無法從中合理恢復的意外情況。我建議在個案的基礎上處理特殊情況:如果你有一個非常具體的方法,你知道它有時會拋出一個非常特殊的異常(以及你知道如何處理它,例如重試),那麼我會在try-catch塊中包裝這個*(只有這個)方法來捕獲* this *(並且只有這個)異常(即'catch(MyExpectedDeadlockException)'而不是'catch(Exception)')並且做一些事情針對這種情況。 – Heinzi

+0

@Yoav:對於所有其他類型的異常,中斷BL操作,記錄,顯示消息並返回到UI是正確的。而這正是這種方法的作用。 – Heinzi

0

首先:總是趕只有異常,您可以處理(See Eric Lippert Post
你可以按照這個策略:

  • 如果不能從異常恢復做在DAL層只並記錄下來。
  • try {} catch{}如果用戶可以處理它在BAL層。
+0

我並不完全同意這種看法,只會捕捉你可以處理的異常。有一些類型的例外是你不能指望的,或者是不值得花時間來嘗試和預測的,例如數據庫相關的或TCP相關的例外情況,你仍然希望讓應用程序\用戶在投擲前重試 – Yoav

+0

@Yoav如果你有意想不到的例外,讓他們崩潰你的過程。這樣,你會意識到它們存在並迫使你處理它們,而不是保持登錄在某個txt文件 –

+0

@YuvalItzchakov所以你會建議不圍繞數據庫操作(當然,讓事務離開)? – Yoav