I am using an approach similar to the one in this ASP.NET MVC tutorial where you pass a wrapper around a controller's ModelState
collection into a validation class so that the controller can access error information.
Here is a cooked up example:
interface IProductValidator {
void Validate(Product item);
}
class ProductValidator {
// constructor
public ProductValidator(ModelStateWrapper validationDictionary) { }
}
interface IProductService {
void AddProduct();
}
public class ProductService : IProductService {
// constructor
public ProductService(IProductValidator validator) { }
}
Using the Castle Windsor container for IoC/DI, how do I create the IProductService
? Typically, I would have:
MvcApplication.IocContainer.Resolve<IProductService>()
but this isn't able to inject the value of the Controller's ModelState
property into the constructor for ProductValidator. I could possibly wire this up using constructor parameters, but that seems really ugly.
I'm assuming you want the modelstate passed in to auto inject any errors into your model? IMHO, ModelState should stay where it is, and you bring the validation errors to it. Here's how I handle errors as an example. I'm not saying this is the best way or the only way, but it is one way where your validation layer doesn't have to have knowledge of who or what consumes validation errors.
First, in my poco, I use
System.ComponentModel.DataAnnotations
for validation rules. Here is my account class, for example.Because I want to be able to initiate validation myself (outside of MVC doing it on it's own), I had to implement my own validator.
Here is the ValidationResult I pass back
ErrorInfo is a very basic class with information about my error
in order to wrap this validation up all nice and neat with my poco classes, I inherit from a base class. For validation to make it generic where the inherited child has to tell the base class it's type. It feels circular, but it works.
And finally, as you can see, my validation throws a RulesException. This class is a wrapper for all the errors.
So, with that said, my validation in my controller looks more like this
ModelState.AddModelStateErrors(ex); is an extension method that I wrote. it is very simple.
This way, I can still use DI for my services/repositories, and let them throw up an error when my model is invalid. Then I let the front end - whether that is an MVC app, web service, or windows app - decide what to do with those errors.
I feel that injecting MVC controller/model/view state back into the model/services/repositories/etc is a violation of the basic separation between the layers.