FluentValidation验证工厂和Ninject DI容器

时间:2012-01-25 13:15:11

标签: c# dependency-injection ninject fluentvalidation

我正在使用NinjectHttpApplication我的项目中定义的几个模块。

我想要的是按照http://www.thekip.nl/2011/09/22/using-fluentvalidation-for-both-domain-validation-and-validation-in-mvc-projects/中的描述创建FluentValidation验证工厂。

要创建具体的验证工厂,我需要覆盖

IValidator CreateInstance(Type validatorType) 

然后我应该调用

的方法
return kernel.Get<validatorType>() as IValidator

但我已经读过,建议不要在Global.asax范围之外使用IKernel。

有什么选择可以制作我想要的东西?

编辑:使用Ninject-FluentValidation扩展程序

正如雷莫所说,GitHubhttps://github.com/ninject/ninject.web.mvc.fluentvalidation)有一个扩展名。扩展中有一个类:

public class NinjectValidatorFactory : ValidatorFactoryBase { ... }

在构造函数中使用IKernel并创建IValidator

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

    return Kernel.Get(validatorType) as IValidator;
}

然后我的代码就像:

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;
    }
}

有效。我不知道它能否更好地解决。另外,我不明白需要在IKernel上公开NinjectValidationFactory作为公共财产。

4 个答案:

答案 0 :(得分:10)

Ninject.Web.Mvc.FluentValidation扩展为Ninject添加了对流畅验证的支持。它可以在NuGet上找到。见https://github.com/ninject/ninject.web.mvc.fluentvalidation

答案 1 :(得分:4)

高度建议阅读Mark Seemann的Dependency Injection in .NET书。

为了简单起见,如果您想要询问容器的依赖关系,那么您就不会使用依赖注入。你没有打电话给容器。它会打电话给你。

答案 2 :(得分:1)

这很简单。我向您展示了一个简单的控制台应用程序,以使用NInject演示FluentValidation。

  1. 在visual studio中创建一个控制台应用程序。
  2. Intsall nuget包FluentValidation和NInject。
  3. cld.uploader.upload('<image>',function(res){console.log(res);},{public_id:"<public_id>"})

    Install-Package NInject

    1. 创建以下类。

      Install-Package FluentValidation

      4.程序类中的主要方法如下:

      public class Customer
      {
          public int Id { get; set; }
          public string Surname { get; set; }
          public string Forename { get; set; }
          public decimal Discount { get; set; }
          public string Address { get; set; }
      }
      
      using FluentValidation;
      public class CustomerValidator : AbstractValidator<Customer>
      {
          public CustomerValidator()
          {
              //RuleFor(customer => customer.Surname).NotNull();
              RuleFor(customer => customer.Surname).NotNull().NotEqual("foo");
          }
      }
      
      using FluentValidation;
      using Ninject;
      using System;
      
      public class NInjectValidatorFactory : ValidatorFactoryBase
      {
          private readonly IKernel m_NInjectKernel;
          public NInjectValidatorFactory(IKernel kernel)
          {
              if (kernel == null)
                  throw new ArgumentNullException("NInject kernel injected is null!!");
      
              m_NInjectKernel = kernel;
          }
          public override IValidator CreateInstance(Type validatorType)
          {
              return m_NInjectKernel.Get(validatorType) as IValidator;
          }
      }
      
      1. 跑吧。代码非常自我解释。在main方法中,我们正在设置DI容器,在这种情况下为NInject。然后我们正在进行必要的绑定(映射)。请注意,只需要一个映射。这也是为了表现而解释here的单身人士。

答案 3 :(得分:0)

根据您的内核实现,这不是问题。

不推荐使用,因为它会在内核上创建依赖关系(因此您使用的是Service Location而不是依赖注入)。

另一种选择是使用Alexsander Beletsky描述的提供者的Ninjects概念。