首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有InversifyJS参数的工厂

带有InversifyJS参数的工厂
EN

Stack Overflow用户
提问于 2016-11-23 14:56:53
回答 1查看 3.5K关注 0票数 3

我将InversifyJS与TypeScript结合使用。

假设我有一个类,它有一个混合了注入和非注入构造函数参数的类:

代码语言:javascript
复制
@injectable()
export class MyClass {
    constructor(
      foo: Foo, // This thing isn't injectable
      @inject(Bar) bar: Bar // This thing is
   ){
      ...
   }
}

我想将这个类的工厂注入到其他类中,然后用第一个参数的值调用它。

代码语言:javascript
复制
@injectable()
export class SomeOtherClass {
   constructor(
      @inject("Factory<MyClass>") myClassFactory: (foo: Foo) => MyClass
   ){
      const someFoo = new Foo();
      const myClass = myClassFactory(someFoo);
   }
}

我的问题是:在Inversify中有什么自动魔法可以让我注入这个工厂吗?

到目前为止,我想出的最好的方法是:

代码语言:javascript
复制
bind<interfaces.Factory<MyClass>>("Factory<MyClass>").toFactory(context =>
    (foo: Foo) => 
        new MyClass(foo, context.kernel.get<Bar>(Bar))
);

但这意味着我是显式的new()-ing MyClass,这里还必须添加MyClass的每个新的可注入依赖项。

有更好的办法吗?也许是基于像Ninject工厂扩展这样的参数名称

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-11-24 14:07:46

我是InversifyJS的作者。我不认为在工厂内部使用new有什么问题,记住工厂的工作是创建一个新的实例。

确实,在工厂中多次调用container.get<T>不是件好事

我可以建议将MyClass的初始化分为几个阶段:

由工厂实例化的类:

代码语言:javascript
复制
@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;
   }

}

使用工厂的类:

代码语言:javascript
复制
@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);
   }
}

工厂:

代码语言:javascript
复制
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问题上的想法。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40767730

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档