2013-11-26 2 views
6

В приложении ASP.Net MVC 4, в котором я сейчас работаю, есть несколько моделей, имеющих свойство хранилища. Я хочу, чтобы все эти модели имели валидацию, которая гарантирует, что введенный склад является допустимым складом. Казалось, что самый простой способ сделать это - использовать специальный класс ValidationAttribute. Тогда код проверки будет централизован, и я мог бы просто добавить атрибут к свойству в каждой из моделей.ASP.Net MVC 4 Custom ValidationAttribute Injection

Мне нужно позвонить в службу, чтобы убедиться, что склад является допустимым складом. У меня есть интерфейс, который представляет эту службу, и я использую Ninject для инъекции зависимостей в моих приложениях, где используется эта служба. Таким образом, я могу использовать насмешку и легко выполнять модульное тестирование в приложении.

Я хочу, чтобы мой пользовательский класс ValidationAttribute использовал инъекцию зависимостей при использовании этой службы. Вот класс, который я создал:

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 в качестве параметра, потому что тогда я считаю, что мне придется передать этот параметр, когда я добавлю этот атрибут в свой класс.

Есть ли способ сделать этот код более пригодным для проверки? Если нет, то есть ли лучший способ приблизиться к этому?

ответ

9

Вы должны использовать класс DependencyResolver в ASP.NET MVC. Если вы правильно подключите свой контейнер, DependencyResolver.Current будет использовать ваш контейнер для разрешения зависимостей.

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 как это:

DependencyResolver.SetResolver(resolverMock); 
+0

отработал отлично, спасибо. –

Смежные вопросы