2011-03-17 28 views
1

我已經建立了一個MVC應用程序看起來像這樣:處理異常,在N層,領域驅動設計,MVC應用程序

MVC Application - Application Layer - Business Layer - Repository - Data

我讀過的many應用程序的代碼,發現無似乎以類似於數據傳遞的方式傳遞異常。

換句話說,數據通過接口被引用並在不同的上下文中重用。如果在數據層發生異常,這會如何發送到GUI或相關層?應該使用接口嗎?在this應用程序中處理異常的構造是什麼?

回答

3

我還沒有閱讀鏈接,但我有一個簡單的情況下,我提出異常,以響應未能滿足不變量。假設我正在創建一個實例,出於某種原因它是「無效的」,假設用戶輸入不正確。而不是使我的實體處於無效狀態(這是DDD中的禁止狀態)並讓系統「驗證」它,它在創建時會引發異常。相關的「驗證消息」(針對用戶)是從相同的規範實例中提取的,這個實例並不滿足,而且我的派生異常包含UI所需的值。的InvariantException

示例:如何

public class PostFieldLengthSpecification : ISpecification<Post> 
{ 
    private const string TITLE_LENGTH_RANGE = "5-100"; 
    private const string BODY_LENGTH_RANGE = "20-10000"; 


    public bool IsSatisfiedBy(Post post) 
    { 
     return this.GetErrors(post).IsValid; 
    } 


    public ModelStateDictionary GetErrors(Post post) 
    { 
     ModelStateDictionary modelState = new ModelStateDictionary(); 

     if (!post.Title.Trim().Length.Within(TITLE_LENGTH_RANGE)) 
      modelState.AddModelError(StongTypeHelpers.GetPropertyName((Post p) => p.Title), 
       "Please make sure the title is between {0} characters in length".With(TITLE_LENGTH_RANGE)); 

     if (!post.BodyMarkup.Trim().Length.Within(BODY_LENGTH_RANGE)) 
      modelState.AddModelError(StongTypeHelpers.GetPropertyName((Post p) => p.BodyMarkup), 
       "Please make sure the post is between {0} characters in length".With(BODY_LENGTH_RANGE)); 

     return modelState; 
    } 
} 

示例:返回相關的 「驗證信息」 對於用戶/ UI規範組成

public class InvariantException : MyAppException 
{ 
    public object FailingObject = null; 
    public ModelStateDictionary ModelState = new ModelStateDictionary(); 


    public InvariantException() { } 

    public InvariantException(object failingObject, ModelStateDictionary messages) 
    { 
     this.FailingObject = failingObject; 
     this.ModelState = messages; 
    } 

    public InvariantException(object failingObject, ModelStateDictionary messages, 
     Exception innerException) 
     : base("refer to ModelState", innerException) 
    { 
     this.FailingObject = failingObject; 
     this.ModelState = messages; 
    } 
} 

實施例工廠永遠不會讓無效實例被創建,而是會拋出一個異常並存儲UI的消息:

public static Post GetNewPost(string title, string bodyMarkup, DateTime posted) 
    { 
     var post = new Post(0, title, bodyMarkup, posted, new List<Comment>()); 
     var fieldLengthSpec = new PostFieldLengthSpecification(); 

     if (fieldLengthSpec.IsSatisfiedBy(post)) 
      return post; 
     else 
      throw new InvariantException(post, fieldLengthSpec.GetErrors(post)); 
    } 

最後,自定義模型粘合劑的示例,其用於捕捉所述異常和「無效對象」回傳給了與錯誤消息的操作:

public class PostModelBinder : DefaultModelBinder 
{ 
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     if (bindingContext.ModelType == typeof(Post)) 
     { 
      try 
      { 
       // Create Post 
       return base.BindModel(controllerContext, bindingContext); 
      } 
      catch (InvariantException ie) 
      { 
       // If invalid, add errors from factory to ModelState 
       bindingContext.ModelState.AddNewErrors(ie.ModelState); 
       bindingContext.ModelState.AddValuesFor<Post>(bindingContext.ValueProvider); 
       return ie.FailingObject; 
      } 
     } 

希望這有助於。