博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
NHibernate.Validator 实体验证框架
阅读量:6694 次
发布时间:2019-06-25

本文共 7636 字,大约阅读时间需要 25 分钟。

     在系统开发时,很多情况下都需要对实体进行验证,比如规定某个属性值不能为空,Email的格式或者电话号码的格式是否正确.这种验证不应该只在UI层进行,主要有以下几方面的考虑:
     1.如果每个层次都相互独立,就不能够完全相信传入数据的有效性.比如如果你的UI代码直接调用了业务层,那么就能够相信任何用户的输入.
     2. 因为每个层次都有可能有复用性.也就是使用环境可能不一样.比如你的Webservice调用了你的业务层,你的UI也调用你的业务层.那么你的验证放在哪?
    所以,在一个企业级系统中,对业务数据进行有效验证是非常有必要的.我觉得一个好框架应该能够满足以下要求:
     1.能够以很方便的方式进行规则验证.一般有属性标识或者XML.
     2.不仅提供丰富的基础的规则验证,而且能够支持对验证直接进行灵活扩展,添加用户自定义规则.
     3.能够很容易插拨.
     4.能够满足在不同的层使用同样的验证规则进行验证.
    到现在为止,我接触过Enterprise Library提供的Validation Application Block()以及开源的验证框架Validation Framework(都符合上面的要求,而且现在他们都提供了对MVC,WPF的支持,相当的不错.
    OK,有点跑题了,言归正传.前段时间在NHibernate Contrib看到NHibernate.Validator项目,它是一个从Hibernate.Validator移植过来的开源项目,其实它和上面的两个验证框架都非常相似,提供的支持和功能基本上也都差不多.NHibernate.Valiator不仅可以对ORM中的业务对象进行验证,它也可以脱离NHibernate单独使用.相同,企业库的Validation Application  Block和Validation Framework不仅可以对我们的业务对象验证,也可以通过事件与NHibernate整合.

    好的,那就来详细介绍一下NHibernate.Validator:

一.下载配置

        首先下载NHibernate.Validator   
        然后在你使用的项目中引用相应的dll 

二. 配置

        NHibernate.Validator的配置有几种方法:
 1.在你的应用程序下面新建文件nhvalidator.cfg.xml,在这个文件中添加配置信息

true
true
UseXml
 

2.程序的app/web.config中添加配置信息

3.全部使用程序进行配置

NHVConfiguration nhvc = new NHVConfiguration();nhvc.Properties[Environment.ApplyToDDL] = "false";nhvc.Properties[Environment.AutoregisterListeners] = "true";nhvc.Properties[Environment.ValidatorMode] = "UseAttribute";nhvc.Mappings.Add(new MappingConfiguration("NHibernate.ValidatorDemo.Model", null));ValidatorEngine validator = new ValidatorEngine();validator.Configure(nhvc);

其实,你如果默认的方式使用,你可以不进行上面的任何配置,直接就可以调用:

ValidatorEngine validator = new ValidatorEngine();bool isValid = validator.IsValid(customer);

     上面的设置中有autoregister_listeners属性就是设置Validator是否自动的监听NHibernate的内置事件PreInsertEvent和PreUpdateEvent,如果为True,就是在实体进行添加和更新前都会对实体进行验证(这里包括级联验证),如果验证没有通过则会发出异常信息. 其实你也可以通过配置手动的监听这两个事件,在你的Hibernate的配置信息中添加:

...
...

    但是我们在哪里能够保证我们调用的ValidatorEngine在我们的应用程序中只有一个实例呢(包括上面的两个监听事件的处理),因为我们这个在不同的层中都要使用的.肯定要保证验证的一致性. (当然也可以不进行这个设置),其中的一个方法就是设置SharedEngineProvider,在上面的配置时添加:

我们先看一下ISharedEngineProvider接口,很简单,就一个方法:

/// 	/// Contract for Shared EngineP rovider	/// 	public interface ISharedEngineProvider	{		/// 		/// Provide the shared engine instance.		/// 		/// 
The validator engine.
ValidatorEngine GetEngine(); }

然后是默认的NHibernateSharedEngineProvider怎么实现这个接口的:

public class NHibernateSharedEngineProvider : ISharedEngineProvider	{		private static readonly ValidatorEngine ve = new ValidatorEngine();		// Explicit static constructor to tell C# compiler not to mark type as before field init		static NHibernateSharedEngineProvider()		{         		}		#region ISharedEngineProvider Members		public ValidatorEngine GetEngine()		{            			return ve;		}		#endregion	}

可以看到,其实也很简单,不过这样的话这里会不会有多线程问题呢?不过这里即使有多线程问题,我觉得这也没有必要.
       4.在使用IOC容器的系统和Web环境下,最好重新实现自己的SharedEngineProvider.不过,在这里介绍怎么在spring.net中配置NHibernate.Validator,并且能够使用DI直接使用声明的Validator对象.因为没有找到能够自动可以注入的ValidatorEngine,我自己实现了一个:
     

public class NHValidatorObject : IFactoryObject, IInitializingObject    {        #region Fields        private ValidatorEngine validator;        private IMessageInterpolator interpolator;        private ValidatorMode defaultMode;        private bool applyToDDL;        private bool autoRegisterListeners;        private string sharedEngineProviderClass;        private string[] mappingAssemblies;        #endregion        ///         /// Default MessageInterpolator        ///         public IMessageInterpolator Interpolator        {            set { interpolator = value; }        }        ///         /// Default Mode to construct validators        ///         public ValidatorMode DefaultMode        {            set { defaultMode = value; }        }        ///         /// Database schema-level validation enabled        ///         public bool ApplyToDDL        {             set { applyToDDL = value; }        }        ///         /// NHibernate event-based validation        ///         public bool AutoRegisterListeners        {            set { autoRegisterListeners = value; }        }        public string SharedEngineProviderClass        {            set { sharedEngineProviderClass = value; }        }        ///         /// Sets the assemblies to load that contain mapping files.        ///         /// 
The mapping assemblies.
public string[] MappingAssemblies { set { mappingAssemblies = value; } } /// /// Return the validator /// ///
The singleon validator factory.
public object GetObject() { return validator; } /// /// Return the type /// ///
The type created by this factory
public System.Type ObjectType { get { return validator.GetType(); } } /// /// Returns true /// ///
true
public bool IsSingleton { get { return true; } } /// /// Initialize validator for the given or the /// default location. /// public virtual void AfterPropertiesSet() { NHVConfiguration config = new NHVConfiguration(); config.Properties.Add(Environment.ApplyToDDL,applyToDDL.ToString()); config.Properties.Add(Environment.AutoregisterListeners,autoRegisterListeners.ToString()); config.Properties.Add(Environment.ValidatorMode, defaultMode.ToString()); foreach(string assembly in mappingAssemblies){ config.Mappings.Add(new MappingConfiguration(assembly,null)); } validator = new ValidatorEngine(); validator.Configure(config); }

         然后在配置文件中声明对象,并且设置属性:

                     
       
       
       
           
               
Demo.Model
           
       
   

 

这样,你就要在你的任何一个层次中从applicationContext或者是通过依赖注入获取ValidatorEngine来完成实体验证了.

三.使用
采用属性定义的方式:

public class Customer{[Length(Min = 3, Max = 20)]public string FirstName{ get; set; }[Length(Min=3, Max = 60)]public string LastName { get; set; }[CreditCardNumber]public string CreditCard { get; set;}}

采用XML映射文件的方式:(注意这里文件要为嵌入式资源,后面要以.nhv.xml结尾)

而且,NHibernate.Validator还支持以上两种方法混合使用.那我们再看一下怎么扩展自己的验证规则,首先先实现IValidator:

public class PhoneValidator : IValidator{     public bool IsValid(object value)     {           Regex regex = new Regex(@"^[2-9]\d{2}-\d{3}-\d{4}$");        if (value == null)     return true;          return regex.IsMatch(value.ToString());       }}

然后是对应的属性标识:

[AttributeUsage(AttributeTargets.Field AttributeTargets.Property)][ValidatorClass(typeof(PhoneValidator))]public class PhoneAttribute : Attribute, IRuleArgs{    private string message = string.Empty;     public string Message    {         get { return message; }         set { message = value; }      }}

四.资料

1.NHibernate Validator 1.0.0 Documentation
2.S#arp Architecture (Castle+AcitiveRecord+NHibernate.Validator)
3.NHibernate.Validator - ASP.NET MVC
4.Diving in NHibernate.Validator
5.NHibernate Validator

作者:()

出处:
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

分类:
标签: , , , , ,
本文转自孤独侠客博客园博客,原文链接:http://www.cnblogs.com/lonely7345/archive/2009/03/15/1412159.html,如需转载请自行联系原作者
你可能感兴趣的文章
[导入]Are Generics in .NET like Templates in C++?
查看>>
[转载]手机软件开发之我见
查看>>
UNITY实现FLASH中的setTimeout
查看>>
C#文件和文件文件夹按时间、名称排序-顺序与倒序
查看>>
表达式的计算结果必须为节点集。
查看>>
法外之徒第一季/全集Braquo迅雷下载
查看>>
人工智能助力阿里云售后服务
查看>>
雅虎出售在即 紧急修改员工遣散协议的控制权变更条款
查看>>
兰州市大数据中心与多部门实现基础数据共享
查看>>
他们做的通用人工智能,要让所有产品都具备“智能”大脑
查看>>
淘富成真平台——微链投资平台
查看>>
英国芯片厂商ARM实现盈利提升,大股东软银表示非常欣慰
查看>>
IDG刘雨坤:关于SaaS业务七点经验
查看>>
Learning Distributed Representations of Sentences from...
查看>>
奥巴马成立新委员会 加强网络安全
查看>>
阿里全渠道开辟新“试验田” 大数据赋能商家
查看>>
解放网络经理:基于软件的网络释放
查看>>
“云计算”和“虚拟化”的区别
查看>>
tpcc-mysql安装、使用、结果解读
查看>>
知错能改的感知机(Perceptron)
查看>>