2011-03-17 26 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; 
      } 
     } 

希望这有助于。