ASP.Net MVC 4自定义ValidationAttribute依赖注入 [英] ASP.Net MVC 4 Custom ValidationAttribute Dependency Injection

查看:1200
本文介绍了ASP.Net MVC 4自定义ValidationAttribute依赖注入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我目前的工作也有一些有一个仓库财产车型ASP.Net MVC 4应用程序。我希望所有这些模型有验证这可以确保进入仓库是一个有效的仓库。这似乎是要做到这一点是使用自定义ValidationAttribute类最简单的方法。然后验证code是集中式的,而且我可以在属性只是添加到属性中的每个型号的。

In a ASP.Net MVC 4 application that I am currently working on there are a number of models that have a warehouse property. I want all of these models to have validation that makes sure that the warehouse entered is a valid warehouse. It seemed like the easiest way to do this was to use a custom ValidationAttribute class. Then the validation code would be centralized, and I could just add the attribute to the property in each of the models.

我需要调用一个服务,以确保仓库是一个有效的仓库。我有一个重新presents这个服务,我用Ninject做在我的应用程序依赖注入在使用这个服务接口。这样我可以用嘲弄的,容易做单元测试应用程序。

I need to call a service to make sure that the warehouse is a valid warehouse. I have a interface that represents this service and I am using Ninject to do dependency injection in my applications where this service is used. That way I can use mocking and easily do unit testing on the application.

我想我的自定义ValidationAttribute类使用这项服务时使用依赖注入。下面是我创建的类:

I want my custom ValidationAttribute class to use dependency injection when using this service. Here is the class that I have created:

public class MustBeValidWarehouse : ValidationAttribute
{
  public override bool IsValid(object value)
  {
    if (value is string)
    {
      string warehouse = value.ToString();
      NinjectDependencyResolver depres = new NinjectDependencyResolver();
      Type inventServiceType = typeof(IInventService);
      IInventService inventserv = depres.GetService(inventServiceType) as IInventService;
      return (inventserv.GetWarehouses().Where(m => m.WarehouseId == warehouse).Count() != 0);

    }
    else
    {
      return false;
    }
  }
}


public class NinjectDependencyResolver : IDependencyResolver
{
    private IKernel kernel;
    public NinjectDependencyResolver()
    {
        kernel = new StandardKernel();
        AddBindings();
    }

    public object GetService(Type serviceType)
    {
        return kernel.TryGet(serviceType);
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        return kernel.GetAll(serviceType);
    }

    private void AddBindings()
    {
        kernel.Bind<IInventService>().To<InventService>();
    }
}

依赖注入工作正常,但它是不容易测试。有没有办法在一个单元测试来注入模拟IInventService进级。通常为了解决这个我会在类的构造函数需要IInventService参数,这样我可以在模拟对象的传入我的单元测试。不过,我不认为我能有这个类的构造函数需要IInventService类作为参数,因为那时我相信我会在参数来传递,当我在我的类添加这个属性。

The dependency injection works correctly, however it is not easy to test. There is no way to inject a mock IInventService into the class in a unit test. Normally in order to resolve this I would have the class constructor take a IInventService parameter so that I could pass in a mock object in my unit test. However I don't think that I can have this class constructor take a IInventService class as a parameter because then I believe that I would have to pass in that parameter when I added this attribute in my class.

有没有办法让这个code的可测试性?如果没有,那么有没有更好的方式来处理这个?

Is there a way to make this code more testable? If not then is there a better way to approach this?

推荐答案

您需要使用 DependencyResolver 类在ASP.NET MVC。如果您正确连接您的容器 DependencyResolver.Current 将使用您的容器来解决的依赖关系。

You need to use DependencyResolver class in ASP.NET MVC. If you wire your container correctly DependencyResolver.Current will use your container to resolve the dependencies.

public class MustBeValidWarehouse : ValidationAttribute
{
    public override bool IsValid(object value)
    {
        if (value is string)
        {
            string warehouse = value.ToString();
            IInventService inventserv = DependencyResolver.Current.GetService<IInventService>();
            return (inventserv.GetWarehouses().Where(m => m.WarehouseId == warehouse).Count() != 0);
        }
        return false;
    }
}

在你的类的测试,你可以为 DepedencyResolver.Current 这样的模拟:

In your class tests you can provide a mock for DepedencyResolver.Current like this:

DependencyResolver.SetResolver(resolverMock);

这篇关于ASP.Net MVC 4自定义ValidationAttribute依赖注入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆