Typescript 定义全局类型脚本配置(接口),用于Aurelia依赖项注入
在Aurelia中,我有几个类依赖于相同的配置。使用IoC/DI,很自然地可以将此配置作为构造函数参数提供。例如: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) {
@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时,这些属性在中是未定义的。难倒。。。就在我想。。。有什么想法吗?