Частичный впрыск Inversify - PullRequest
0 голосов
/ 08 мая 2018

Как частичное введение свойств можно сделать с помощью Inversify?

Допустим, у нас есть класс

class MyClass {
    constructor(
        @inject(EXTERNAL_A) private externalA: ExternalClassA,
        private b: string
    ) {}
}

Как я могу использовать этот MyClass с inversify в других классах, если все возможные значения b известны во время компиляции. Итак, мне нужно только для экземпляров MyClass один с b = "a", а другой с b = "b".

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

В первом случае мне нужно написать что-то подобное

container.bind<MyClass>(CLASS_A).toConstantValue(
    new MyClass(container.get<ExternalClassA>(EXTERNAL_A), "a")
);

container.bind<MyClass>(CLASS_B).toConstantValue(
    new MyClass(container.get<ExternalClassA>(EXTERNAL_A), "b")
);

Выглядит довольно грязно и не решает следующую проблему, а также фабрики, не решающие ее. Если у меня есть глубокая иерархия объектов в этом случае, мне нужно построить их все через эту цепочку создания объектов вручную.

Какой лучший способ здесь?

Задача со звездочкой, если возможно разрешить какое-то дерево зависимостей с заменой одной и той же зависимости на предоставленную? Мол, у нас может быть что-то вроде

 |-----B-----e
A|-----C-----e
 |-----D
 |-----e

Так что я не хочу заменять e зависимость своей построенной. Как мне этого добиться?

1 Ответ

0 голосов
/ 05 июля 2018

Привет,

Боюсь, идеального решения не существует. В этом случае я обычно использую фабричный шаблон с методом set или setup.

Пример:

interface MyInterface {
     myPublicMethod();
}

type MyInterfaceFactoryA = () => MyInterface;
type MyInterfaceFactoryB = () => MyInterface;

class MyClass extends MyInterface {

     private b: string;

     constructor(
          @inject(EXTERNAL_A) private externalA: ExternalClassA,
     ) {}

     public setup(b: string): void {
          this.b = b;
     }

}

Когда вы настраиваете свой контейнер, обычно в пределах ContainerModule, вам нужно сделать что-то вроде этого:

 bind<MyClass>("MyClass").to(MyClass);

 container.bind<MyInterface>(CLASS_A).toConstantValue(
      const myClass = context.container.get<MyClass>("MyClass");
      return myClass.setup("a");
 );

 container.bind<MyInterface>(CLASS_B).toConstantValue(
     const myClass = context.container.get<MyClass>("MyClass");
     return myClass.setup("a");
 );

А потом просто используйте это:

 class MyOtherClass {

      constructor(
          @inject(CLASS_A) private _myInterfaceInstanceA: MyInterface,
          @inject(CLASS_B) private _myInterfaceInstanceB: MyInterface) {

      }

 }

Надеюсь, это поможет вам. Вы можете найти больше информации об этом на: https://github.com/inversify/InversifyJS/issues/530

...