Инверсия управления для возвращаемого объекта

2

У меня есть метод, возвращающий ISomething. Я пытаюсь использовать Inversion of Control во всей моей программе... но я не знаю, как это сделать, когда дело доходит до возвращаемого значения - я не могу передать его методу или объекту при его создании, потому что этот метод должен создать объект.

Единственное решение, которое я вижу, - передать объект ISomething factory (Func<ISomething>) объекту при его создании. Это обычное/правильное решение или что-то еще рекомендуется?

[Изменить] Странно - у кого-то еще не было этой проблемы? Я имею в виду, что нет (или даже меньше) голосования...

[Изменить] Подробнее: метод должен импортировать IExcel в ITable. Консенсус ниже, похоже, заключается в том, что я должен думать об этом методе как о конвертере, превращая IExcel в ITable, получая как аргументы, а не возвращающие значение ITable. Я оставлю это еще на один день, а затем перейду с одним из ответов, если ничего нового не появится.

  • 0
    Вы должны поместить свои комментарии от ответа @Philip Rieck в вопрос. Описание ISomething немного расплывчато, но в этих комментариях вы сталкиваетесь с особенностями, которые, вероятно, позволят получить лучшие ответы.
Теги:
inversion-of-control

3 ответа

2
Лучший ответ

Предполагается ли, что ваш метод должен создать ISomething или установить его состояние и вернуть ISomething с инициализацией состояния? (или это должна быть одна операция?)

Если у вашего класса есть метод, который отвечает за создание ISomething, то это ISomethingFactory (если у вас нет смешанных проблем). В этом случае у него есть логика, чтобы выбрать правильную реализацию ISomething и создать ее, поэтому вам не следует слишком беспокоиться о аспекте IoC.

Однако, если этот класс не создает соответствующий ISomething, я бы, вероятно, передал factory. Проблема заключается в том, что в большинстве случаев ваш контейнер DI должен иметь возможность сделать это за вас (назовите factory, чтобы получить соответствующий ISomething), поэтому просмотр метода, который должен создать ISomething, который не является factory, заставляет меня нервничать.

Попытка дать архитектурное руководство всегда жесткая на форуме, подобном этому, хотя, но с ограниченным объемом ввода я бы сказал, что у вас есть factory, который вы не знали, это factory, или у вас есть проблема.

  • 0
    Интересно. Это должно построить что-то. Метод читает файл Excel и возвращает ITable (какой тип ITable является проблемой) - некоторое время я буду работать с таблицей в памяти, но я хочу переключиться на таблицу SQLite или даже SQL Server в некоторых случаях. точка). Звучит странно, если учесть, что мой класс импортеров - это ITable фабрика ...
  • 0
    Думая "вслух" еще немного ... если я не выберу вариант "мой класс - фабрика ITable", мне кажется, что я должен рассматривать его как конвертер, а не как импортер. Таким образом, он может принимать два аргумента, файл Excel и (вне) ITable, и преобразовывать первый во второй. Я думаю, мне придется спать на нем, но спасибо за мозговой штурм :)
Показать ещё 1 комментарий
1

"У меня есть объект, который должен создать объект и что-то сделать с ним, но я не хочу, чтобы объект знал, какой объект создается, за исключением того, что он должен иметь определенный интерфейс".

Это похоже на описание учебника абстрактного шаблона Factory, что предполагает, что ваш объект имеет зависимость от соответствующего factory.

который также аккуратно разделяет обязанности - один объект отвечает за создание объекта соответствующего типа, а другой отвечает за выполнение операций над ним, прежде чем возвращать его.

  • 0
    Спасибо; хорошая точка зрения.
0

В конструкторе объекта, который содержит метод, возвращающий ISomething, получите экземпляр контейнера IoC. Затем метод, который создает экземпляр ISomething, может использовать контейнер IoC для получения объекта с правильным типом.

то есть:

public class ExcelImporter
{
    private IObjectFactory ObjectFactory { get; set; }

    public ExcelImporter(IObjectFactory objectFactory)
    {
        ObjectFactory = objectFactory;
    }

    public ITable Import()
    {
        var result = ObjectFactory.Get<ITable>();
        { Do import here }
        return result;
    }
}
  • 0
    Это работает как метод "как это сделать" ... Я искал ответ "должен ли я сделать это таким образом, и если да, то почему" :)
  • 0
    Ну, это скорее философская дискуссия; Вы никогда не получите жесткий быстрый ответ. :-) Тем не менее, я не испытываю особого сожаления по поводу того, как я это сделал. Он оставляет экземпляр объекта с контейнером IoC, к которому он принадлежит. Таким образом, он позволяет проводить тестирование, предоставляя контейнеру IoC тестовую реализацию ITable в тестовой среде. ...
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню