ASP.NET MVC 5: внедрение репозитория в IValidatableObject

У меня есть класс, реализующий интерфейс 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, когда он будет создан.

так что не так с кодом, который вы разместили? Вы ищете, как настроить ядро ​​/ привязку ninject, чтобы сделать ваш код возможным?

GregH 14.11.2018 18:46

@GregH Я даже не знаю, можно ли заставить его работать. Теперь класс репозитория настроен в файле NinjectWebCommon, и он работает правильно, когда дело доходит до ввода в контроллеры, но я не могу заставить его внедрить в опубликованный мною класс, в основном потому, что я не создаю экземпляр этого класса, он MVC, который создает его с помощью входящего запроса. Я хотел бы знать, как внедрить его в опубликованный мною класс.

amedina 15.11.2018 08:47

Похоже, вы делаете это немного неправильно. Я думаю, вы хотите внедрить интерфейс для репо в конкретный класс SelectedFilteringCriteria, тогда как вы упомянули попытку внедрить его в интерфейс IValidatableObject. Что плохого в том, чтобы внедрить интерфейс вашего репо в конкретный класс SelectedFilteringCriteria? Вот как я снова и снова видел, как поступает DI. Я не уверен, зачем вам нужно что-то вводить в сам интерфейс. Может быть, еще немного контекста поможет

GregH 15.11.2018 14:03

если у вас есть несколько классов, которые наследуются от IValidatableObject и вам нужно, чтобы ваше репо было введено в каждый из них, тогда создайте базовый класс, в который будет внедрен ваш интерфейс репо, а затем унаследуйте от них другие классы. Таким образом, подпись класса будет выглядеть примерно как SelectedFilteringCriteria : BaseCriteria, IValidatableObject, где репо вводится в BaseCriteria, чтобы все классы, которые унаследовали от него, имели доступ к вашему репо.

GregH 15.11.2018 14:05

@GregH Я не говорил, что хочу внедрить класс в интерфейс, это абсурд. Хорошо, проще говоря: FiltersRepository должен быть введен в SelectedFilteringCriteria через конструктор. Как я могу этого добиться, учитывая, что это не я, а MVC создает экземпляр класса SelectedFilteringCriteria. В итоге: это проблема конфигурации: как я могу настроить MVC и Ninject для этого?

amedina 15.11.2018 14:35

Что ж, «Я хотел бы знать, есть ли способ сказать MVC внедрить класс репозитория в IValidatableObject», это наверняка звучит так, как будто вы пытаетесь внедрить что-то в интерфейс. Извините за путаницу. В любом случае Ninject все равно, кто создает экземпляр класса. Возьмем, к примеру, контроллер. Никто не new подбирает контроллер. MVC создает его для вас, и в любом случае он работает одинаково. Я думаю, ваша проблема отличается от описанной. Я откажусь от этого вопроса ... удачи

GregH 15.11.2018 14:43
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
6
142
1

Ответы 1

Нет, похоже, это невозможно, потому что класс MutableObjectModelBinder, который MVC 5 использует для создания соответствующего объекта (SelectedFilteringCriteria в моем случае) из параметров действия, использует System.Activator вместо разрешения зависимостей, которые SelectedFilteringCriteria мог иметь с помощью текущего DependencyResolver.

Обходной путь для этого может заключаться в том, чтобы сделать это внутри конструктора SelectedFilteringCriteria:

public SelectedFilteringCriteria()
{
    _filtersRepository = DependencyResolver.Current.GetService<IFiltersRepository>();
}

Но это могло подъехать к Сервис Локатор Антипаттерн. Твой выбор.

Другие вопросы по теме