Недоумение по принципу инъекции зависимостей - что, если он зависит от времени выполнения, какие объекты создаются?

, который я создаю , использует ASP.NET Core, который во многих случаях требует использования инъекции зависимостей. Для меня это новое и противоречивое. До сих пор мне удалось ограничить использование инъекции зависимостей там, где это строго требуется каркасом, при написании механики игры в «моем» старом виде, то есть с большим количеством явных создания объектов ( ---- +: = 0 =: + ---- и т. д.) (и без создания интерфейсов, когда их реализует только один класс.)

Прочитав немного об инъекции зависимостей, которую документация Framework рекомендует использовать повсюду, я был озадачен, обнаружив, что я не должен вызывать конструкторы или явно создавать какие-либо объекты, потому что вместо этого я должен запросить все объекты, которые мне бы хотелось var blah = new SomeClass(arg1, arg2), чтобы создать в конструкторе ClassA и пусть рамки предоставят их мне!

Скрываясь над моим кодом, во многих случаях я не вижу, как я мог это сделать. Простое перемещение всех ClassA s в конструктор не работает.

Одним из примеров является то, что кажется, что время выполнения зависит от того, какие объекты должны быть созданы.

Чтобы быть более конкретным, позвольте мне привести пример для этого примера: P Существует много символов new, которые могут использовать:

Move

и др.

Клиент (веб-браузер) обычно отправляет серверу команду с именем перемещения, которое игрок хотел бы выполнить. Опуская множество необходимых проверок (для простоты), это код соответствующего метода сервера:

public class Punch : Move
{
    // ...
}

public class SwordSlash : Move
{
    // ...
}

Правильно - сервер просто выглядит, если есть класс, чье имя эквивалентно строке, отправленной клиентом. Ну, нарушение вливания инъекций?

Итак, как мне это сделать?

Единственный способ, который приходит мне на ум, - это иметь класс, у которого contructor будет принимать ВСЕ (в настоящее время 79 и подсчет) ходов, и у него будет метод с гигантским переключателем, чтобы выбрать правильный ход:

var moveType = System.Type.GetType("Game.Mechanics."+moveTypeName);
if (!(moveType.BaseType == typeof(Move))) return; // OK one of the many validations I did not omit
move = (Move)Activator.CreateInstance(moveType, args);

Я как-то чувствую, что это не правильный путь. Тем более, что добавление нового хода теперь будет довольно утомительным.

Итак, как мне исправить свой код, чтобы я не нарушал правило, которое я должен избегать ключевого слова public class MoveSelector : IMoveSelector { private readonly IPunch punch; private readonly ISwordSlash swordSlash; // 77 more privates public MoveSelector ( IPunch punch, ISwordSlash swordSlash, // 77 more args ) { this.punch = punch; this.swordSlash = swordSlash; // 77 more assignments } public IMove SelectMove(string moveName) { switch(moveName) { case "Punch": return punch; case "SwordSlash": return swordSlash; // 77 more cases } } }

1 голос | спросил gaazkam 13 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowThu, 13 Sep 2018 22:53:10 +0300 2018, 22:53:10

1 ответ


1

Инъекция зависимости не должна использоваться без размышлений и определенно не везде.

В современной разработке приложений внедрение зависимостей в значительной степени необходимо для классов обслуживания (компонентов), то есть тех классов, для которых действительно имеет смысл иметь только один экземпляр во всем приложении. Примерами этого могут быть сам контейнер внедрения зависимостей, экземпляры репозитория, возможно, HTTP-клиент, ...

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

Если у вас есть класс, экземпляр которого зависит от времени выполнения, и этот класс зависит от объекта службы, создание экземпляров таких объектов обычно выполняется с использованием фабрики (где фабрика является классом обслуживания), например, как это:

class MyClassDependendOnServiceClass
{
    public MyClassDependendOnServiceClass(userInput: UserInput, service: Service)
    {
        // ...
    }
}

class MyClassDependendOnServiceClassFactory
{
    private Service service;

    public MyClassDependendOnServiceClassFactory(service: Service)
    {
        this.service = service;
    }

    public MyClassDependendOnServiceClass Create(userInput: UserInput)
    {
        return new MyClassDependendOnServiceClass(userInput, this.service);
    }
}

Затем вы вводите экземпляр фабрики, например, в. контроллер и получить объект MyClassDependendOnServiceClass, используя его.

Если ваши ходы не зависят от чего-либо подобного и должны создаваться каждый раз, просто сделайте это. Там нет проблем с этим.

ответил Andy 13 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowThu, 13 Sep 2018 23:07:17 +0300 2018, 23:07:17

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132