2010-08-29 4 views
0

У меня есть эти слои в моем приложении:Это 4-уровневая архитектура хорошо (обработка исключений важна для меня :)

  • Entities
  • базы данных (с Сущности ссылка)
  • бизнеса (с ссылки на базы данных и Entities)
  • Пользовательский интерфейс (с бизнес и Entities ссылки)

Вот пример моих кодов:

  • UserDAL класс в слое базы данных:

public class UsersDal 
{ 
    databaseDataContext db; 
    public UsersDal() 
    { 
     try 
     { 
      db = new databaseDataContext(ConnectToDatabase.GetConnectionString()); 
     } 
     catch (Exception ex) 
     { 
      throw ex; 
     } 
    } 
    public List<User> GetAllUsers() 
    { 
     try 
     { 
      return (from u in db.Users select u).ToList(); 
     } 
     catch (Exception ex) 
     { 
      throw ex; 
     } 
    } 

И так далее ...


В UserBLL класс в бизнес-слое я пишу вот так:

public class UsersBll 
{ 
    UsersDal user; 
    public UsersBll() 
    { 
     try 
     { 
      user = new UsersDal(); 
     } 
     catch(Exception ex) 
     { 
      throw new ProjectException(Errors.CannotCreateObject, ex); 
     } 
    } 
    public List<User> GetAllUsers() 
    { 
     try 
     { 
      return user.GetAllUsers(); 
     } 
     catch(Exception ex) 
     { 
      throw new ProjectException(Errors.CannotReadData, ex); 
     } 
    } 

И в UI я пишу:

private void GetUsers() 
    { 
     try 
     { 
      UsersBll u = new UsersBll(); 
      datagrid.DataSource = u.GetAllUsers(); 
     } 
     catch(ProjectException ex) 
     { 
      MessageBox(ex.UserMessage);// and also can show ex.InnerException.Message for more info 
     } 
    } 

Ну, я использую ProjectException с именем класса для получения ошибки содержат BLL создано сообщение мною и сообщением Exception, что операционная система автоматически манипулировать. Также я создать перечисление возможных ошибок и словарь здесь есть некоторые подробности о нем:

namespace Entities 
{ 
    public enum Errors 
    { 
     CannotCreateObject, 
     CannotReadData, 
     CannotAdd, 
     CannotEdit, 
     CannotDelete,... 
    } 

[global::System.Serializable] 
public class ProjectException : Exception 
{ 
    public ProjectException(Errors er, Exception ex) 
     : base(errors[er], ex) 
    { 
     currentEx = er;//er is Errors enum 
    } 
    static ProjectException() 
    { 
     errors = new Dictionary<Errors, string>(); 
     errors.Add(Errors.CannotCreateObject, "the application cannot connect to database!"); 
     errors.Add(Errors.CannotReadData, "the application cannot read data from database"); //... 
    } 
    public string UserMessage 
    { 
     get 
     { 
      try 
      { 
       return errors[currentEx]; 
      } 
      catch 
      { 
       return "Unknown error!"; 
      } 
     } 
    } 

Является ли это хорошо? это работает для меня хорошо. Что вы думаете?

ответ

1

Это почти всегда неправильно в пределах catch (ex), чтобы сделать throw ex;. Либо просто сделайте throw; или еще throw new whateverException("someMessage", ex);. Решение о том, следует ли использовать прежнюю форму или последнюю, обычно зависит от того, пересекаете ли вы прикладной уровень. Если AcmeServerDatabaseWrapper, который происходит из типа DatabaseWrapper, выполняет запрос при вызове метода AcmeDatabaseTableNotFoundException, он должен поймать это и реконструировать его как исключение DatabaseWrapperTableNotFoundException (если такой тип существует) или как исключение DatabaseWrapperOperationFailedException. Клиентский код, который имеет объект, производный от DatabaseWrapper, должен знать, какие типы исключений будут выбрасывать объект, не зная, какой тип объекта он имеет. Любое исключение, которое выходит из уровня базы данных без обертывания, является исключением, клиентский код вряд ли сможет обрабатывать разумно, но может ошибочно обрабатывать (думая, что это произошло в контексте, отличном от того, где это произошло на самом деле).