4

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

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

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

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

这样可行。我不知道它是否可以更好地解决。另外我不明白需要IKernelNinjectValidationFactory.

4

4 回答 4

10

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

于 2012-02-01T00:04:10.587 回答
4

强烈建议阅读 Mark Seemann 的.NET 中的依赖注入一书。

为简单起见,如果您要向容器询问依赖项,则没有使用依赖注入。你不调用容器。它会打电话给你。

于 2012-12-15T20:07:00.290 回答
1

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

  1. 在 Visual Studio 中创建控制台应用程序。
  2. Intsall nuget 包 FluentValidation 和 NInject。

Install-Package NInject

Install-Package FluentValidation

  1. 创建以下类。

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

    4.程序类中的main方法如下。

    using FluentValidation;
    using Ninject;
    using System;
    using System.Linq;
    
    class Program
    {
        static void Main(string[] args)
        {
            // Set up the DI Container.
            var kernel = new StandardKernel();
            kernel.Bind<IValidator<Customer>>().To<CustomerValidator>().InSingletonScope();
    
            var nInjectvalidationFactory = kernel.Get<NInjectValidatorFactory>();
            var customer = kernel.Get<Customer>();
    
            var customerValidator = nInjectvalidationFactory.GetValidator<Customer>();
    
            var results = customerValidator.Validate(customer);
    
            if (!results.IsValid)
                results.Errors.ToList().ForEach(e =>
                {
                    Console.WriteLine(e.ErrorMessage);
                    Console.WriteLine(e.ErrorCode);
                    Console.WriteLine(e.PropertyName);
                    Console.WriteLine(e.ResourceName);
                    Console.WriteLine(e.Severity);
                }
                );
            Console.ReadLine();
        }
    }
    
    1. 运行这个。该代码非常不言自明。在 main 方法中,我们设置了 DI 容器,在本例中为 NInject。然后我们正在做必要的绑定(映射)。注意只需要一个映射。这也是一个单例,正如这里解释的性能。
于 2017-06-29T13:27:51.800 回答
0

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

不建议这样做,因为它会创建对内核的依赖项(因此您使用的是服务位置而不是依赖项注入)。

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

于 2012-01-25T14:24:36.103 回答