我在 MVC4 项目中使用 FluentValidation 。 完美无缺,并且与 IoC ( StructureMap )相关联。
我有两个问题:
我应该如何管理验证器的生命周期?可以让他们单身吗?或者没有区别,我可以根据我的需要管理生命周期?这里的最佳做法是什么?
FluentValidation 非常好。我一直在使用它来进行简单验证(例如:属性不为空等)。我正在考虑使用它进行一些 Db验证(例如:属性值是唯一的。)我可以使用<将存储库传递给它strong> StructureMap 并检查Db的值。 这是个好主意吗?或者我应该在服务层中而不是在我的IValidator中实现此逻辑?
如果您在类似场景中使用过它,那么您的体验是什么?
答案 0 :(得分:5)
我已经使用了FluentValidation多年了,并且已经询问并找出了你的问题。
我个人建议你不要使用单身。
对此疯狂,这是FluentValidation的一大优势,只需确保依赖性在时间和资源方面并不昂贵。
答案 1 :(得分:4)
我刚刚使用Unity和MVC 4来调查此事。
我所看到的是,如果你将它们保留为瞬态物体。 FluentValidation将为每个已验证的属性创建新的验证对象。所以需要一些缓存。
对于我的缓存,我已经查看了验证器的Per Request缓存。这适用于所有依赖组件是按请求。 (Per Request是自定义代码,它在HttpContext.Current.Items集合中存储子Unity容器,其中HTTP模块在请求结束时销毁/丢弃子容器)
要在验证器的Per Request和Singleton时刻之间进行选择,可以归结为如何使用它以及它具有哪种类型的依赖关系以及IoC Continer的能力。
使用unity可以创建单例验证器并使用函数(即Func serviceFunc)注入服务工厂。
在我的情况下,每次调用serviceFunc时,都会检索Unity ChildContiner“服务”。因此,我仍然可以使用ContainerControlledLifetimeManager(singleton)定义我的'validator',并使用HierarchicalLifetimeManager(Per Request)定义'service'。
这样做的缺点是每次调用serviceFunc时都需要检查并从子容器中检索服务。这将是我回到'每个请求'的最可能原因)
我刚刚更新了我的代码以使用serviceFunc,并将在今天进行测试。我相信为您的申请找到正确的解决方案将是一次错误的尝试。
下面是我正在使用的验证工厂 - 而不是使用统一容器(如网上的大多数示例),我正在将IDependencyResolver
注入其中并使用它来解析我的验证器对象。
public class ValidatorFactory : IValidatorFactory
{
private readonly IDependencyResolver _dependencyResolver;
// taken from the attribute Validation factory
public ValidatorFactory(IDependencyResolver dependencyResolver)
{
_dependencyResolver = dependencyResolver;
}
/// <summary>
/// Gets a validator for the appropriate type.
///
/// </summary>
public IValidator<T> GetValidator<T>()
{
return (IValidator<T>)this.GetValidator(typeof(T));
}
/// <summary>
/// Gets a validator for the appropriate type.
///
/// </summary>
public virtual IValidator GetValidator(Type type)
{
if (type == (Type)null)
return (IValidator)null;
var validatorAttribute = (ValidatorAttribute)Attribute.GetCustomAttribute((MemberInfo)type, typeof(ValidatorAttribute));
if (validatorAttribute == null || validatorAttribute.ValidatorType == (Type) null)
{
return (IValidator) null;
}
else
{
return _dependencyResolver.GetService(validatorAttribute.ValidatorType) as IValidator;
}
}
}
答案 2 :(得分:2)
验证不足为奇,通常取决于您的应用程序的架构,但这是我的想法。
验证员应根据您的需要进行管理。我通常会将静态类实例留给典型的服务基础设施问题,如工厂或对象构建器。
毫无疑问,FluentValidation库非常棒。验证面临的典型问题不是您选择的库的结果,而是应用验证的方式。在大多数典型的应用程序中,对象/实体/域的验证是上下文的,因此验证完全取决于您尝试执行的操作的上下文。例如,对于持久性,更改属性,更改状态,ETL等,对同一对象的验证可能不同。记住所有这些我相信验证属于尽可能接近正在执行的操作。
希望这有帮助。