Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript 定义全局类型脚本配置(接口),用于Aurelia依赖项注入_Typescript_Dependency Injection_Aurelia - Fatal编程技术网

Typescript 定义全局类型脚本配置(接口),用于Aurelia依赖项注入

Typescript 定义全局类型脚本配置(接口),用于Aurelia依赖项注入,typescript,dependency-injection,aurelia,Typescript,Dependency Injection,Aurelia,在Aurelia中,我有几个类依赖于相同的配置。使用IoC/DI,很自然地可以将此配置作为构造函数参数提供。例如: @autoinject export class CustomerService { constructor(config: IRemoteServiceConfig) { } } @autoinject export class GummyBearService { constructor(config: IRemoteServiceConfig) {

在Aurelia中,我有几个类依赖于相同的配置。使用IoC/DI,很自然地可以将此配置作为构造函数参数提供。例如:

@autoinject
export class CustomerService {
    constructor(config: IRemoteServiceConfig) {
    }
}

@autoinject
export class GummyBearService {
    constructor(config: IRemoteServiceConfig) {
    }
}
在最简单的示例中,IRemoteServiceConfig可能如下所示(为了简洁起见,删除了其他内容):

将配置注入构造函数是测试的理想选择,不需要我阅读每个类中的配置和设置

这些服务依赖于相同的配置,我想在启动期间在应用程序中定义一次

通过阅读,我发现有几种方法可用于此目的,例如
registerInstance()
registerResolver()
registerSingleton()
。文档中确实缺少一些关于如何以及在何处定义的上下文

在我的启动例程的
configure()
部分中,我从以下内容开始:

// register a static config; for brevity these are hardcoded settings
// but could come from anywhere
container.registerSingleton(IRemoteServiceConfig, () => {
    return <IRemoteServiceConfig> {
        endpoint: 'http://foo.com/api/v23/',
        apiKey: 'abc'
    }
});
//注册一个静态配置;为简洁起见,这些是硬编码设置
//但可能来自任何地方
container.registerSingleton(IRemoteServiceConfig,()=>{
返回{
端点:'http://foo.com/api/v23/',
阿皮奇:“abc”
}
});
它似乎什么也没发现(没有错误)。但这也可能只是我对如何初始化容器的无知

我的问题:如果可以的话,我如何在Aurelia中定义IRemoteServiceConfig,以及在哪里定义,这样一旦DI为服务启动,它就会自动选择我的(硬编码)配置

请注意,其中提到“它不能与接口一起工作,因为TypeScript会在运行时编译这些接口。”。这个问题已经有2年了,无论是在奥雷利亚还是在打字本中都发生了很大的变化。不管这种情况是否仍然存在,同样的问题也适用于类的实例,而不是接口


另外请注意,我知道libs,例如,似乎适合将appsettings存储在配置文件中(并且工作正常)。这对于给出的示例更有意义。但问题完全与如何定义接口或类的特定实例有关,这些接口或实例将由Aurelia DI解决

无论使用哪个TypeScript版本,运行时都不存在接口

为了同时用作接口和DI令牌,
IRemoteServiceConfig
应该是一个类:

export abstract class IRemoteServiceConfig { ... }

@estus提供的答案是正确的,我已将其标记为答案。尽管如此,我还是遇到了一些额外的问题来让它正常工作。为了指出这一点,我花了时间在下面写了一个包含更多细节的答案,希望它能在将来帮助其他人

1.使用类,而不是接口
与接受的答案状态一样,您不能使用接口-它必须是一个类

2.通过aurelia.container访问全局容器实例
文档没有提到如何获取容器的实例。但是您可以通过
aurelia.container
直接调用
configure()
操作中的默认/全局容器,如下所示:

aurelia.container.registerSingleton(RemoteServiceConfig, () => {
  var config = new RemoteServiceConfig();
    config.endpoint = 'http://foo.com/api/v23/',
    config.apiKey = 'abc'
});
我在初始化Container()的新实例时出错,并试图以某种方式将其注入configure()操作中。我不应该:)

3.将您的课程分成不同的文件
这看起来很傻,但很重要:这些类不能在同一个文件中,否则会出现以下错误:

键/值不能为null或未定义。您是否正在尝试注入/注册DI中不存在的内容

对于原始问题,我在同一app.ts文件中创建了所有类。而这似乎根本不起作用

综上所述,完整的应用程序现在看起来是这样的,并且可以工作:

main.ts

import { Aurelia } from 'aurelia-framework'
import { RemoteServiceConfig } from './app';

export function configure(aurelia: Aurelia) {
  aurelia.use
    .standardConfiguration()
    .feature('resources');

  aurelia.container.registerSingleton(RemoteServiceConfig, () => {
    var config = new RemoteServiceConfig();
      config.endpoint = 'http://foo.com/api/v23/',
      config.apiKey = 'abc'
  });

  aurelia.start().then(() => aurelia.setRoot());
}
import { autoinject } from 'aurelia-dependency-injection';

// note: classes below should be 3 different files!

@autoinject
export class App {
  constructor(private service: CustomerService) {
  }
}

@autoinject
export class CustomerService {
  constructor(private config: RemoteServiceConfig) {
  }
}

export class RemoteServiceConfig {
  public endpoint: string;
  public apiKey?: string;
}
应用程序ts

import { Aurelia } from 'aurelia-framework'
import { RemoteServiceConfig } from './app';

export function configure(aurelia: Aurelia) {
  aurelia.use
    .standardConfiguration()
    .feature('resources');

  aurelia.container.registerSingleton(RemoteServiceConfig, () => {
    var config = new RemoteServiceConfig();
      config.endpoint = 'http://foo.com/api/v23/',
      config.apiKey = 'abc'
  });

  aurelia.start().then(() => aurelia.setRoot());
}
import { autoinject } from 'aurelia-dependency-injection';

// note: classes below should be 3 different files!

@autoinject
export class App {
  constructor(private service: CustomerService) {
  }
}

@autoinject
export class CustomerService {
  constructor(private config: RemoteServiceConfig) {
  }
}

export class RemoteServiceConfig {
  public endpoint: string;
  public apiKey?: string;
}

谢谢如问题中所述,我仍然对如何在我的Aurelia应用程序中定义它以及在哪里定义它感到困惑(例如,像如何在configure()中“初始化”容器)?当接口更改为类时,container.registerSingleton是否仍然不适用于您?很明显,通常情况下,您会希望在应用程序的主配置方法中预先进行此配置。事实上,这似乎可以做到这一点。我接受了这个答案。虽然我遇到了一些其他问题,我写了一个额外的答案。很高兴它对您有所帮助。您只需将配置类注入应用程序并填充它,您不必手动注册它。我实际上要做的是注入另一个名为ConfigLoader的类,它本身接受配置,并有一个“load”方法。应用程序调用ConfigLoader.load,填充注入配置的值(不要替换对象)。因为这些都在顶级DI容器中,任何其他注入配置的组件都将获得这些值。:)@这是真的。尽管我个人更喜欢使用前面提到的aurelia配置。当然,为configs找到一种不同的方法不是问题。很高兴我找到了这篇文章。我需要从我存储在所有模块都可以访问的单例中的web服务中获取一些信息。我已经完全按照你的解决方案去做了,但我无法使它发挥作用。这看起来是个时间问题。当web服务响应时,Aurelia已经启动并加载了根元素。我可以将配置单例注入到其他元素中,但Web服务中的数据不在其中。我甚至像您一样在中初始化了一些属性,但当其他类访问singleton时,这些属性在中是未定义的。难倒。。。就在我想。。。有什么想法吗?