2015-06-21 3 views
1

У меня есть следующий сценарий, когда я называю метод в моем коде доступа к данным из моего бизнес-слоя:попытка поймать блок место

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

Метод например в DAL:

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

Я бы предложил третий вариант: Положите регистрацию ошибок и отображение ошибок в слое пользовательского интерфейса.

Зарегистрируйте central error handler в своем пользовательском интерфейсе. Там вы можете

  • дисплей ошибка (либо простой MessageBox или фантазии окно с «более подробно» и «Отчет для разработчиков» кнопки) и

  • регистрировать все,

без помех каждый BL-метод с уловками-catch-all try-catch.

Это имеет много преимуществ:

  • Это будет сделать легче читать ваш код BL.
  • Вы не можете забыть a BL метод.
  • Легче сделать (централизованное) изменение кода обработки ошибок.
  • Вы не связываете свою бизнес-логику с конкретным типом пользовательского интерфейса, который имеет множество преимуществ самостоятельно: например, вы можете повторно использовать его в веб-проекте позже, и вы можете проверить свою бизнес-логику с модульные испытания.
+0

Однако это интересный подход, как я мог узнать после вызова метода исключения, если он сработал или нет (_i.e_ следует ли повторить вызов или прекратить выполнение остальной части кода и вернуть его)? – Yoav

+0

@Yoav: * Усушно *, исключения - это нечто неожиданное, от которого вы не можете разумно оправиться. Я бы предложил обрабатывать особые случаи в каждом конкретном случае: если у вас есть очень специфический метод, о котором вы знаете, что он иногда генерирует очень специфическое исключение (и где вы знаете, что делать против него, например, повторить попытку) то я бы обернул этот * (и только этот) метод в блок try-catch, который ловит * это * (и только это) исключение (т.е. 'catch (MyExpectedDeadlockException)', а не 'catch (Exception)') и что-то делает для этого случая. – Heinzi

+0

@Yoav: для всех остальных типов исключения прерывание операции BL, ведение журнала, отображение сообщения и возврат в пользовательский интерфейс - это правильная вещь. И это именно то, что сделал бы этот подход. – Heinzi

0

Прежде всего: Всегда поймать только исключения можно обрабатывать (See Eric Lippert Post)
Вы можете следовать этой стратегии:

  • Если вы не можете оправиться от исключения сделать это в DAL слоя только и запишите его.
  • try {} catch{} в слое BAL, если пользователь может его обработать.
+0

Я не полностью согласен с восприятием только в том, чтобы ловить исключения, с которыми вы можете справиться. есть некоторые типы исключений, которые вы не можете ожидать, или не стоит тратить время, чтобы попытаться предсказать такие связанные с БД или связанные с TCP исключениями, которые вы все равно хотите разрешить приложению \ пользователю повторять попытку, прежде чем бросать – Yoav

+0

@Yoav Если у вас есть неожиданные исключения, пусть они разрушают ваш процесс. Таким образом, вы будете знать, что они существуют и заставляют вас обращаться с ними, вместо того, чтобы оставаться в каком-то txt-файле –

+0

@YuvalItzchakov, так что бы вы предложили не окружать операцию БД вообще (и, конечно же, оставлять транзакции в стороне)? – Yoav