使用FluentValidation时,如何基于Type而非泛型T获取IValidationContext?
非泛型IValidator结合FluentValidation的实现问题
我定义了一个包含ValidateObject(object instance)方法的IValidator接口,希望以FluentValidation为底层验证框架实现该接口。参考相关讨论后,我已成功获取到非泛型的FluentValidation.IValidator,但其Validate方法需要IValidationContext实例。由于此时无法知晓泛型T,找不到创建或获取IValidationContext的方法。
请问是否可以通过如下代码实现?
Type genericType = typeof(IValidator<>).MakeGenericType(instance.GetType()); var validator = (FluentValidation.IValidator) _container.GetInstance(genericType); var context = new ValidationContext<object>(instance, new PropertyChain(), new DefaultValidatorSelector()); var validationResult = validator.Validate(context);
有没有办法基于实例的Type(如instance.GetType())而非泛型T来获取该上下文?
解决方案
首先,你提供的代码可以正常工作,但有更简洁、精准的方式创建对应类型的ValidationContext,以下是两种推荐方案:
方案一:反射动态创建泛型ValidationContext
通过反射为实例的实际类型创建对应泛型版本的ValidationContext,避免用object作为泛型参数:
Type genericType = typeof(IValidator<>).MakeGenericType(instance.GetType()); var validator = (FluentValidation.IValidator)_container.GetInstance(genericType); // 动态生成对应实例类型的ValidationContext var contextGenericType = typeof(ValidationContext<>).MakeGenericType(instance.GetType()); var context = Activator.CreateInstance(contextGenericType, instance, new PropertyChain(), new DefaultValidatorSelector()); var validationResult = validator.Validate((IValidationContext)context);
方案二:使用FluentValidation内置的非泛型上下文创建方法
FluentValidation提供了无需指定泛型的上下文创建工具ValidationContext.CreateWithOptions,直接传入实例即可:
Type genericType = typeof(IValidator<>).MakeGenericType(instance.GetType()); var validator = (FluentValidation.IValidator)_container.GetInstance(genericType); // 非泛式创建验证上下文 var context = ValidationContext.CreateWithOptions(instance, options => { options.Selector = new DefaultValidatorSelector(); }); var validationResult = validator.Validate(context);
原有代码的可行性说明
你用ValidationContext<object>包装实例的方式是可行的,FluentValidation内部会处理类型适配,但上述两种方案能更精准匹配实例的实际类型,减少潜在的类型转换风险。
内容的提问来源于stack exchange,提问作者Steven
相关产品推荐
相关产品推荐

