У меня есть метод, возвращающий ISomething
. Я пытаюсь использовать Inversion of Control во всей моей программе... но я не знаю, как это сделать, когда дело доходит до возвращаемого значения - я не могу передать его методу или объекту при его создании, потому что этот метод должен создать объект.
Единственное решение, которое я вижу, - передать объект ISomething
factory (Func<ISomething>
) объекту при его создании. Это обычное/правильное решение или что-то еще рекомендуется?
[Изменить] Странно - у кого-то еще не было этой проблемы? Я имею в виду, что нет (или даже меньше) голосования...
[Изменить] Подробнее: метод должен импортировать IExcel в ITable. Консенсус ниже, похоже, заключается в том, что я должен думать об этом методе как о конвертере, превращая IExcel в ITable, получая как аргументы, а не возвращающие значение ITable. Я оставлю это еще на один день, а затем перейду с одним из ответов, если ничего нового не появится.
Предполагается ли, что ваш метод должен создать ISomething или установить его состояние и вернуть ISomething с инициализацией состояния? (или это должна быть одна операция?)
Если у вашего класса есть метод, который отвечает за создание ISomething, то это ISomethingFactory (если у вас нет смешанных проблем). В этом случае у него есть логика, чтобы выбрать правильную реализацию ISomething и создать ее, поэтому вам не следует слишком беспокоиться о аспекте IoC.
Однако, если этот класс не создает соответствующий ISomething, я бы, вероятно, передал factory. Проблема заключается в том, что в большинстве случаев ваш контейнер DI должен иметь возможность сделать это за вас (назовите factory, чтобы получить соответствующий ISomething), поэтому просмотр метода, который должен создать ISomething, который не является factory, заставляет меня нервничать.
Попытка дать архитектурное руководство всегда жесткая на форуме, подобном этому, хотя, но с ограниченным объемом ввода я бы сказал, что у вас есть factory, который вы не знали, это factory, или у вас есть проблема.
"У меня есть объект, который должен создать объект и что-то сделать с ним, но я не хочу, чтобы объект знал, какой объект создается, за исключением того, что он должен иметь определенный интерфейс".
Это похоже на описание учебника абстрактного шаблона Factory, что предполагает, что ваш объект имеет зависимость от соответствующего factory.
который также аккуратно разделяет обязанности - один объект отвечает за создание объекта соответствующего типа, а другой отвечает за выполнение операций над ним, прежде чем возвращать его.
В конструкторе объекта, который содержит метод, возвращающий 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;
}
}