Инверсируйте правильный способ внедрения зависимостей во многие классы домена - PullRequest
0 голосов
/ 18 ноября 2018

У меня проблемы с выяснением того, как обрабатывать зависимости и инъекции в остальном веб-сервисе, созданном с помощью машинописи. Я пытаюсь избежать зависимости от inversify от классов моего домена по принципу инверсии зависимостей. На данный момент это структура проекта:

core/ (domain classes)
expressjs/ (web service context)
inversify/ (the injection magic for my domain classes should happen here)
other-modules/ (concrete interface implementations on 3rd party techs)

Это пример того, как мои классы выглядят:

interface DomainInterface {
    foo(): void;
}

interface DomainService {
    bar();
}

class ConcreteClass implements DomainInterface {
    constructor(colaborator: DomainService) { }

    foo() {
        this.colaborator.bar();
        ...
    }
}

Теперь я хочу внедрить все зависимости через inversify, но я не хочу изменять все мои классы домена, чтобы сделать их инъекционными через @injectable decorator.

Одна вещь, которую я, хотя, делал класс, который содержит @injectable зависимость от модуля inversify, который наследует для каждого класса домена, который мне нужно ввести. Например:

@injectable()
class InverisfyConcreteClass extends ConcreteClass {
    constructor(@inject(DomainService) colaborator: DomainService) {
        super(colaborator);
    }
}

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

Другой подход заключался в создании класса «Context», который содержит ссылку на все классы, привязывает их к контейнеру и извлекает их при необходимости:

class InversifyInjectionContext {
    container: Container;

    bind() {
        // bind all needed instances somehow (??)
    }

    concreteClass() {
        return container.get<ConcreteClass>();
    }

    concreteDomainService() {
        return container.get<AnyConcreteDomainService>();
    }
}

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

Как лучше всего решить эту проблему?

1 Ответ

0 голосов
/ 20 ноября 2018

Я наконец решил эту проблему, декорировав каждый класс во время выполнения:

InversifyContext {
    container: Container;

    bindConcreteClass() {
        decorate(injectable(), InverisfyConcreteClass);
        decorate(inject("ColaboratorDomainService"), InverisfyConcreteClass, 0);
        this.container.bind("InverisfyConcreteClass").to(DomainInterface);
    }

    bindColaboratorDomainService() {
        decorate(injectable(), ColaboratorDomainService);
        this.container.bind("ColaboratorDomainService").to(DomainService);
    }
}

Таким образом, я избежал зависимости от конкретной технологии внедрения для любого класса домена, оставляя их чистыми.

...