I'm using FluentValidation in my MVC4 project. Every thing works perfectly and it's connected to my IoC (StructureMap).
I have 2 questions:
How should I manage lifecycle of my validators? Is it ok to make them singleton? or it makes no difference and I can manage lifecycle according to my needs? What is the best practice here?
FluentValidation is very good. I have been using it for simple validations (like: property is not empty, etc.). I'm thinking about doing some Db validations using it(like: property value is unique.) I can pass my repository to it using StructureMap and check values against Db. Is this a good idea? or should I implement this logic in my service layer and not in my IValidator?
If you used it in similar scenarios, what was your experience?
I've used FluentValidation for years now and have asked and figured out your questions.
I personally recommend you DON'T use singletons.
Go crazy with this, it is a huge advantage of FluentValidation, just make sure the dependency isn't expensive in regards to time and resources.
I have just been looking into this myself using unity and MVC 4.
What I have seen is that if you keep them as Transient objects. FluentValidation will create a new validation object for every property that is been validated. So some caching is required.
For my caching I have looked at Per Request caching of the validator. This works well as all the dependent components are Per Request. (Per Request is custom code which stores a child Unity Container on the HttpContext.Current.Items collections with a HTTP module that destroys/dispose the Child Container at the end of the request)
To choose between Per Request and Singleton instants of the validator comes down to how your using it and what type of dependencies it has and the capablities of the IoC Continer.
With unity you can create a singleton validator and inject the service factory using a function ie Func serviceFunc.
In my case each time I call the serviceFunc, the Unity ChildContiner 'service' is retrieved. Thus I can still have my 'validator' defined with a ContainerControlledLifetimeManager(singleton) and have the 'service' defined with HierarchicalLifetimeManager(Per Request).
A downside of this is each time the serviceFunc is invoked it needs to check and retrieves the service from the child container. This will be the most likely reason why I will do back to 'per request')
I have just updated my code to use serviceFunc and will test it today. I believe it will be trial an error to find the correct solution for your aplications.
Below is the validtion factory I'm using - instead of using the unity container (as most examples on the web do), I'm injecting the IDependencyResolver
into it and using that to resolve my validator objects.
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;
}
}
}
Validation is unsurprisingly a complex and usually depends on the architecture for your application, but here are my thoughts.
Validators should be managed according to your needs. I would typically leave static class instances to typically serving infrastructure concerns like factories or object builders.
Without doubt the FluentValidation library is great. Typical problems faced by validation are not a result of the library you choose but the way in which validation is applied. In most typical application validation of an object / entity / domain is contextual, whereby validation depends completely on the context of the operation you’re trying to perform. For example validation on the same object is likely to be different for persistence, changing an attribute, changing state, for ETL, etc. Keeping all of this in mind I believe that validation belongs as close to the operation being performed as possible.
Hopefully this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With