Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FluentValidation validation factory and Ninject DI container

I'm using NinjectHttpApplication with couple modules defined in my project.

What I want is to create FluentValidation validation factory as described in http://www.thekip.nl/2011/09/22/using-fluentvalidation-for-both-domain-validation-and-validation-in-mvc-projects/.

To create a concrete validation factory I need to override

IValidator CreateInstance(Type validatorType) 

method where I should then call

return kernel.Get<validatorType>() as IValidator

But I've read that using IKernel outside of Global.asax scope is not recommended.

What options are there to make what I want?

EDIT: using Ninject-FluentValidation extension

As Remo's stated there's an extension on GitHub (https://github.com/ninject/ninject.web.mvc.fluentvalidation). There's a class in the extension:

public class NinjectValidatorFactory : ValidatorFactoryBase { ... }

which takes IKernel in constructor and creates instances of IValidator

public override IValidator CreateInstance(Type validatorType)
{
    if(((IList<IBinding>)Kernel.GetBindings(validatorType)).Count == 0)
    {
        return null;
    }

    return Kernel.Get(validatorType) as IValidator;
}

then my code goes like:

public class MvcApplication : NinjectHttpApplication
{
    private NinjectValidatorFactory nvfactory;

    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());                        
    }
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            "Default",
            "{controller}/{action}/{id}",
            new { controller = "Employee", action = "Index", id = UrlParameter.Optional }
        );
    }        
    protected override void OnApplicationStarted()
    {
        AreaRegistration.RegisterAllAreas();
        RegisterRoutes(RouteTable.Routes);

        ModelValidatorProviders.Providers.Clear();
        ModelValidatorProviders.Providers.Add(new FluentValidationModelValidatorProvider(nvfactory));            
    }
    protected override IKernel CreateKernel()
    {
        var kernel = new StandardKernel();
        kernel.Load(Assembly.GetExecutingAssembly());            
        nvfactory = new NinjectValidatorFactory(kernel);

        return kernel;
    }
}

That works. I don't know could it be resolved better though. Also I don't understand the need to expose IKernel as a public property on NinjectValidationFactory.

like image 357
lexeme Avatar asked Dec 07 '22 16:12

lexeme


1 Answers

The Ninject.Web.Mvc.FluentValidation extension adds support for fluent validation to Ninject. It can be found on NuGet. See https://github.com/ninject/ninject.web.mvc.fluentvalidation

like image 165
Remo Gloor Avatar answered Dec 26 '22 00:12

Remo Gloor