zoukankan      html  css  js  c++  java
  • 业务逻辑层的设计(二)——让领域模型支持验证

    在之前的随笔《业务逻辑层的设计(一)》已经提到了领域对象模型如何支持验证了。

    本篇随笔将对领域模型继续强化。

    DomainObject为所有领域模型的基类,只要让我们的领域模型继承这个基类,也就实现了通用的验证接口ISupportsValidation。

    ConstraintValidator中封装了使用验证框架的操作,配合ValidationErrorValidationError使外界调用不需要了解验证框架的API。

        public interface ISupportsValidation
        {
            bool IsValid { get; }
            IList<ValidationError> Validate();
        }

    ISupportsValidation接口使得所有的领域模型都具备验证的功能,而DomainObject则实现了具体的验证,使得我们所有的领域模型都有通用的验证模块。

        /// <summary>
        /// 所有领域模型的基类
        /// </summary>
        public class DomainObject:ISupportsValidation
        {
            public virtual bool IsValid
            {
                get
                {
                    try
                    {
                        return ConstraintValidator.IsValid(this);
                    }
                    catch
                    {
                        return false;
                    }
                }
            }
    
            IList<ValidationError> ISupportsValidation.Validate()
            {
                IList<ValidationError> errors;
                errors = (IList<ValidationError>)ConstraintValidator.Validate(this);
                return errors;
            }
        }


    其中的ConstraintValidator类中引用了微软企业库5.0的验证模块,这个设计是为了保持其他层对验证框架的透明化,使用时也就不必引用验证框架了。

        using Microsoft.Practices.EnterpriseLibrary.Validation;
    
        public class ConstraintValidator
        {
            public static bool IsValid(DomainObject domainObj)
            {
                ValidationResults results = Validation.Validate(domainObj);
                return results.IsValid;
            }
    
            public static IList<ValidationError> Validate(DomainObject domainObj)
            {
                IList<ValidationError> errors = new List<ValidationError>();
                ValidationResults results = Validation.Validate(domainObj);
                if (!results.IsValid)
                {
                    foreach (ValidationResult result in results)
                    {
                        ValidationError error = new ValidationError();
                        error.Key = result.Key;
                        error.Message = result.Message;
                        errors.Add(error);
                    }
                }
                return errors;
            }
    
        }


    使用微软企业库来简化代码的复杂度,将会看到User继承了DomainObject,

    但是在领域模型中还是需要引入using Microsoft.Practices.EnterpriseLibrary.Validation命名空间和属性,

    但比起完全自己动手写规则,的确要简化很多了。

        public class User : DomainObject
        {
            private Department _department = new Department();
            private IList<Role> _roles = new List<Role>();
            /// <summary>
            /// ID
            /// </summary>
            [NotNullValidator(MessageTemplate="标识不能为空")]
            public virtual int ID
            {
                get;
                set;
            }
            /// <summary>
            /// LoginName
            /// </summary>
            [StringLengthValidator(50, MessageTemplate = "登录名称必须在50个字符以内")]
            public virtual string LoginName
            {
                get;
                set;
            }
            /// <summary>
            /// Password
            /// </summary>
            [StringLengthValidator(20, MessageTemplate = "密码长度必须在20个字符以内")]
            public virtual string Password
            {
                get;
                set;
            }
            /// <summary>
            /// DepartmentID
            /// </summary>
            public virtual Department Department
            {
                get { return _department; }
                set { _department = value; }
            }
            /// <summary>
            /// Name
            /// </summary>
            public virtual string Name
            {
                get;
                set;
            }
    
            /// <summary>
            /// CreateTime
            /// </summary>
            public virtual DateTime CreateTime
            {
                get;
                set;
            }
    
            /// <summary>
            /// Roles
            /// </summary>
            public virtual IList<Role> Roles
            {
                get { return _roles; }
                set { _roles = value; }
            }
    
            
        }


    可以发现领域模型比上一次的要简洁很多,细心的同学应该发现类中使用了许多virtual,

    那是为了支持数据访问层的延迟加载功能,关于延迟加载原理可以看下 另一篇

    让我们来体验一下吧

            [Test]
            public void TranRollbackTest()
            {
                IDataContext context = DataContextFactory.GetDataContext();
                User user1 = new User() { Name = "adama1", Password = "123123" };
                User user2 = new User() { Name = "adama2", Password = "123123" };
                if (!user1.IsValid)
                {
                    ISupportsValidation user1Vali = user1;
                    IList<ValidationError> errors= user1Vali.Validate();
                    foreach (ValidationError error in errors)
                    {
                        Console.WriteLine("{0}:{1}",error.Key,error.Message);
                    }
                }
                context.BeginTransaction();
                context.Add(user1);
                context.Add(user2);
                context.Rollback();
            }

    由于我们在LoginName属性加了验证条件,所以验证并不会通过,

    输出结果:LoginName:登录名称必须在50个字符以内

    上面的context是我探索ORM原理时自制的上下文,也是一个用到了前一篇提到的工作单元uow,暂时不必理会。

  • 相关阅读:
    如何实现1080P延迟低于500ms的实时超清直播传输技术
    直播体验深度优化方案——连麦互动直播
    前向纠错码(FEC)的RTP荷载格式
    C++通过COM接口操作PPT
    neo4j的搭建和实例使用
    【neo4j】neo4j Desktop1.1.9,windows 安装
    Neo4j删除节点和关系、彻底删除节点标签名
    知识图谱赵军学习笔记(五)--实体消歧
    实体消歧简介
    svn服务器时间与本地时间不同步解决
  • 原文地址:https://www.cnblogs.com/13yan/p/3192526.html
Copyright © 2011-2022 走看看