2016-11-23 2 views
1

Я использую InversifyJS с TypeScript.Завод с параметрами в InversifyJS

Скажем, у меня есть класс, который имеет смесь вводили и не-инжектированных параметров конструктора:

@injectable() 
export class MyClass { 
    constructor(
     foo: Foo, // This thing isn't injectable 
     @inject(Bar) bar: Bar // This thing is 
    ){ 
     ... 
    } 
} 

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

@injectable() 
export class SomeOtherClass { 
    constructor(
     @inject("Factory<MyClass>") myClassFactory: (foo: Foo) => MyClass 
    ){ 
     const someFoo = new Foo(); 
     const myClass = myClassFactory(someFoo); 
    } 
} 

Мой вопрос: есть некоторые авто магии в Inversify, что позволит мне вводить этот завод?

Лучшее, что я придумал до сих пор это:

bind<interfaces.Factory<MyClass>>("Factory<MyClass>").toFactory(context => 
    (foo: Foo) => 
     new MyClass(foo, context.kernel.get<Bar>(Bar)) 
); 

Но это означает, что я явно new() -ную MyClass и каждый новый инъекционный зависимость MyClass должен быть добавлен здесь.

Есть ли лучший способ? Возможно, что-то основано на именах параметров, таких как Ninject Factory Extensions?

ответ

0

Я являюсь автором InversifyJS. Я не думаю, что есть проблема с использованием new внутри фабрики, помните, что задачей фабрики является создание нового экземпляра.

Это правда, что вызов container.get<T> несколько раз внутри фабрики - not a good thing.

я могу предложить разорвать инициализацию MyClass в фазам:

Класс экземпляра на заводе-изготовителе:

@injectable() 
export class MyClass { 

    public c: C; // This thing isn't injectable 
    public d: D; // This thing isn't injectable 

    // PHASE 1: instantiation 
    constructor(
     @inject(A) a: A // This thing is 
     @inject(B) b: B // This thing is 
    ){ 
     ... 
    } 

    // PHASE 2: initialization 
    public init(c: C, d: D) { 
     this.c = c; 
     this.d = d; 
    } 

} 

Класс, который использует завод:

@injectable() 
export class SomeOtherClass { 
    constructor(
     @inject("Factory<MyClass>") myClassFactory: (c: C, d: D) => MyClass 
    ){ 
     // you only use "new" with entities that are not injected by inversify 
     const c = new C(); 
     const d = new D(); 
     const myClass = myClassFactory(c, d); 
    } 
} 

И завод:

bind<interfaces.Factory<MyClass>>("Factory<MyClass>").toFactory(context => 
    (c: C, d, D) => { 

     // PHASE 1: instantiation 
     let myClass = context.kernel.get<MyClass>("MyClass"); // a and b are injected 

     // PHASE 2: initialization 
     myClass.init(c, d); // c and d are initialized 

     return myClass; 

    } 
); 

Я надеюсь, что это поможет и, пожалуйста, поделитесь своими идеями с проблемами GitHub, если вы считаете, что знаете лучший способ.

+1

Благодарим за это. Это определенно улучшает необходимость «get()» каждой зависимости класса. Тем не менее, я могу предложить другой подход к GitHub. –

Смежные вопросы