我一直在使用统一和 MVC 4 自己研究这个问题。
我所看到的是,如果您将它们保留为瞬态对象。FluentValidation 将为每个已验证的属性创建一个新的验证对象。所以需要一些缓存。
对于我的缓存,我查看了验证器的 Per Request 缓存。这很好用,因为所有依赖组件都是 Per Request。(每个请求是自定义代码,它在 HttpContext.Current.Items 集合上存储一个子 Unity 容器,并带有一个在请求结束时销毁/处置子容器的 HTTP 模块)
在验证器的 Per Request 和 Singleton 瞬间之间进行选择取决于您如何使用它,它具有什么类型的依赖关系以及 IoC Continer 的功能。
通过统一,您可以创建一个单例验证器并使用函数(即 Func serviceFunc)注入服务工厂。
就我而言,每次调用 serviceFunc 时,都会检索 Unity ChildContiner 的“服务”。因此,我仍然可以使用 ContainerControlledLifetimeManager(singleton) 定义我的“验证器”,并使用 HierarchicalLifetimeManager(Per Request) 定义“服务”。
这样做的一个缺点是每次调用 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;
}
}
}