У меня есть класс, реализующий интерфейс IValidatableObject, чтобы проверять входящие данные, введенные пользователем. Проблема в том, что для проверки этих данных мне нужно использовать класс, реализующий шаблон репозитория данных, который находится в другой сборке. Что-то вроде этого:
public class SelectedFilteringCriteria : IValidatableObject
{
private IFiltersRepository _filtersRepository;
public SelectedFilteringCriteria(IFiltersRepository filtersRepository)
{
_filtersRepository = filtersRepository;
}
public int? SelectedValue { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var results = new List<ValidationResult>();
var valueOk = _filtersRepository.GetFilters().Any(
filter => filter.Value == SelectedValue
);
if (!valueOk)
{
results.Add(new ValidationResult("Not good :("));
}
return results;
}
}
Я использую контейнер зависимостей Ninject. Я хотел бы знать, есть ли способ сказать MVC внедрить класс репозитория в IValidatableObject, когда он будет создан.
@GregH Я даже не знаю, можно ли заставить его работать. Теперь класс репозитория настроен в файле NinjectWebCommon, и он работает правильно, когда дело доходит до ввода в контроллеры, но я не могу заставить его внедрить в опубликованный мною класс, в основном потому, что я не создаю экземпляр этого класса, он MVC, который создает его с помощью входящего запроса. Я хотел бы знать, как внедрить его в опубликованный мною класс.
Похоже, вы делаете это немного неправильно. Я думаю, вы хотите внедрить интерфейс для репо в конкретный класс SelectedFilteringCriteria, тогда как вы упомянули попытку внедрить его в интерфейс IValidatableObject. Что плохого в том, чтобы внедрить интерфейс вашего репо в конкретный класс SelectedFilteringCriteria? Вот как я снова и снова видел, как поступает DI. Я не уверен, зачем вам нужно что-то вводить в сам интерфейс. Может быть, еще немного контекста поможет
если у вас есть несколько классов, которые наследуются от IValidatableObject и вам нужно, чтобы ваше репо было введено в каждый из них, тогда создайте базовый класс, в который будет внедрен ваш интерфейс репо, а затем унаследуйте от них другие классы. Таким образом, подпись класса будет выглядеть примерно как SelectedFilteringCriteria : BaseCriteria, IValidatableObject, где репо вводится в BaseCriteria, чтобы все классы, которые унаследовали от него, имели доступ к вашему репо.
@GregH Я не говорил, что хочу внедрить класс в интерфейс, это абсурд. Хорошо, проще говоря: FiltersRepository должен быть введен в SelectedFilteringCriteria через конструктор. Как я могу этого добиться, учитывая, что это не я, а MVC создает экземпляр класса SelectedFilteringCriteria. В итоге: это проблема конфигурации: как я могу настроить MVC и Ninject для этого?
Что ж, «Я хотел бы знать, есть ли способ сказать MVC внедрить класс репозитория в IValidatableObject», это наверняка звучит так, как будто вы пытаетесь внедрить что-то в интерфейс. Извините за путаницу. В любом случае Ninject все равно, кто создает экземпляр класса. Возьмем, к примеру, контроллер. Никто не new подбирает контроллер. MVC создает его для вас, и в любом случае он работает одинаково. Я думаю, ваша проблема отличается от описанной. Я откажусь от этого вопроса ... удачи





Нет, похоже, это невозможно, потому что класс MutableObjectModelBinder, который MVC 5 использует для создания соответствующего объекта (SelectedFilteringCriteria в моем случае) из параметров действия, использует System.Activator вместо разрешения зависимостей, которые SelectedFilteringCriteria мог иметь с помощью текущего DependencyResolver.
Обходной путь для этого может заключаться в том, чтобы сделать это внутри конструктора SelectedFilteringCriteria:
public SelectedFilteringCriteria()
{
_filtersRepository = DependencyResolver.Current.GetService<IFiltersRepository>();
}
Но это могло подъехать к Сервис Локатор Антипаттерн. Твой выбор.
так что не так с кодом, который вы разместили? Вы ищете, как настроить ядро / привязку ninject, чтобы сделать ваш код возможным?