【问题标题】:Request a a type from container by type in Aurelia?在 Aurelia 中按类型从容器中请求一个类型?
【发布时间】:2016-08-02 18:23:00
【问题描述】:

在带有 Spring 的 Java 中,如果我想让一个实例知道可以处理它的东西,我会写这样的东西

interface Executable<T extends Executor> {
   Class<T> executorClass();
}

Executable instance = () -> MyExecutor.class;
Class<T> execClazz = instance.executorClass();
T executor = context.getBean( execClazz );
Results r = executor.execute( instance );

我可以将此模式与 Aurelia 和 Typescript 一起使用吗?如果是这样,我如何在 Typescript 中定义 executorClass 的返回类型(我不知道它们用于 Class 或如何简单地返回它)。我如何从 Aurelia 的 Container 中获取类型?

【问题讨论】:

    标签: typescript aurelia


    【解决方案1】:

    您可以使用get 方法从容器中请求一个类型的实例:

    class Foo {
    }
    
    let foo = container.get(Foo); // returns an instance of Foo.
    

    在 TypeScript 中,您可能希望转换 get 方法的结果:

    class Foo {
    }
    
    let foo = <Foo>container.get(Foo); // returns an instance of Foo.
    

    如果您有多种类型实现了特定接口,请在应用启动时注册相应的实现:

    // interface
    class FooService {
      getFoos(): Promise<Foo[]> {
        throw new Error('not implemented'); 
      }
    }
    
    class HttpFooService {
      getFoos(): Promise<Foo[]> {
        return fetch('https://api.evilcorp.com/foos')
          .then(response => response.json());
      }
    }
    
    class MockFooService {
      getFoos(): Promise<Foo[]> {
        return Promise.resolve([new Foo()]);
      }
    }
    
    // app startup... configure the container...
    if (TEST) {
      container.registerHandler(FooService, c => c.get(MockFooService));
      // or: container.registerInstance(FooService, new MockFooService());
    } else {
      container.registerHandler(FooService, c => c.get(HttpFooService));
      // or: container.registerInstance(FooService, new HttpFooService());
    }
    
    // now when you @inject(Foo) or container.get(Foo) you'll get an instance of MockFooService or HttpFooService, depending on what you registered.
    let foo = container.get(Foo); // returns an instance of MockFooService/HttpFooService.
    

    我不确定这是否完全回答了您的问题。我从来没有使用过 Spring,也有一段时间没有做过任何 Java 编程。我没有完全遵循您问题中的代码。 Here's a link 到几个可能有用的容器/DI 用例。这是另一个可能有用的stackoverflow answer。这是 Aurelia DI docs

    附带说明,尽可能远离 container.get。使用它违反了依赖倒置原则。最好列出您的依赖项而不是主动检索它们:

    好(ES6):

    @inject(Foo, Bar)
    class Baz {
      constructor(foo, bar) {
      }
    }
    

    好(打字稿):

    @autoinject
    class Baz {
      constructor(foo: Foo, bar: Bar) {
      }
    }
    

    不太好:

    class Baz {
      constructor() {
        let foo = container.get(Foo);
        let bar = container.get(Bar);
      }
    }
    

    【讨论】:

    • 使用 .get( Type ) 而不是按类型注入的原因是您实际上并不提前知道您想要什么类型,通常这是因为您依赖于一个接口,它有多个可注入实现,但您只需要其中一个,您的参数可以告诉您是哪一个。看你不会写container.get(Foo) 那会很糟糕你写constructor( param ) { this.type = container.get( param.type() ) }。无论如何,您只缺少一个部分。我不确定如何从参数中返回类型,似乎在 Typescript 中找不到 Class 对象/类型。
    • 我想我可以简单地做type() { return Foo },但这并没有给出一个很好的接口方法签名。
    猜你喜欢
    • 1970-01-01
    • 2018-07-17
    • 2011-02-22
    • 1970-01-01
    • 2014-08-28
    • 2020-06-16
    • 2016-04-08
    • 2021-09-13
    • 1970-01-01
    相关资源
    最近更新 更多