我正在尝试Inversify.js我正在使用的Typescript应用程序.现在,没有涉及框架,所以它是纯粹的ES2015.
我正在尝试按照主页面中的示例进行操作,但当我尝试在浏览器中运行时,我遇到了:"Reflect.hasOwnMetadata不是函数".
我正在使用Webpack作为包捆绑器.
这是我的文件夹结构:
这是主要的app.ts文件:
/// <reference path="../typings/index.d.ts" />
/// <reference path="./domain/abstract/match.interface.ts" />
import kernel from "../inversify/inversify.config.ts";
import {symbols} from "../inversify/symbols.ts";
var ninja = kernel.get<INinja>("INinja");
ninja.fight();
ninja.sneak();
Run Code Online (Sandbox Code Playgroud)
interfaces.d.ts:
interface INinja {
fight(): string;
sneak(): string;
}
interface IKatana {
hit(): string;
}
interface IShuriken {
throw();
}
Run Code Online (Sandbox Code Playgroud)
inversify.config.ts
/// <reference path="../node_modules/inversify/type_definitions/inversify/inversify.d.ts" />
/// <reference path="../node_modules/reflect-metadata/reflect-metadata.d.ts" />
/// <reference path="inversify.ts" />
import {Kernel} from "inversify"
//import {MatchHub} from "../app/components/Hubs/match/match-hub.component.ts";
//import {symbols} from "./symbols.ts";
import {Ninja, Katana, Shuriken} from "./inversify.ts";
var kernel …Run Code Online (Sandbox Code Playgroud) 我一直在尝试理解 Inversify @tagged和@named绑定之间的区别。我似乎找不到任何定义两者之间差异的文档。它们看起来相当同义词。
此外,当使用容器的autoBindInjectable设置时,我更困惑如何/在哪里定义对象的标签或名称。似乎没有办法使用注释@injectable()。使用什么作为标识符来绑定对象?它使用类作为标识符吗?
我确实看到inversify-binding-decorators库添加了@provide()和@fluentProvide().whenTargetTagged()装饰器,但这是否@injectable()完全消除了对装饰器的需要?
文档表明:
Run Code Online (Sandbox Code Playgroud)let container = new Container({ autoBindInjectable: true }); container.isBound(Ninja); // returns false container.get(Ninja); // returns a Ninja container.isBound(Ninja); // returns true
但是,除了通用文档之外,它没有显示/指示如何使用@injectable()注释来允许自动绑定:
@injectable()
class Ninja implements Warrior {}
Run Code Online (Sandbox Code Playgroud)
那么如何定义@tagged或@named绑定呢?@tagged还有选择的理由吗@named?或者是使用该库的唯一方法inversify-binding-decorators?
inversion-of-control typescript inversifyjs inversify-binding-decorators
是否可以使用 InversifyJS 获得以下行为:
constructor(IDependency resolvedDependency, string myLiteral)
^ ^
Automatically resolve Defined Literal
Run Code Online (Sandbox Code Playgroud)
如果是这样,最好的方法是什么?
我有TypeScript应用程序,我正在使用Inversify for IoC.
我有一个连接类:
'use strict';
import { injectable } from 'inversify';
import { createConnection, Connection } from "typeorm";
import { Photo, PhotoMetadata, Author, Album } from '../index';
@injectable()
class DBConnectionManager {
public createPGConnection(): Promise<Connection> {
return createConnection({
driver: {
type: "postgres",
host: "host",
port: 5432,
username: "username",
password: "password",
database: "username"
},
entities: [
Photo, PhotoMetadata, Author, Album
],
autoSchemaSync: true,
});
}
}
export { DBConnectionManager };
Run Code Online (Sandbox Code Playgroud)
在我创建连接后,我想将连接绑定到我的容器中:
kernel.bind<Connection>('DefaultConnection').toConstantValue(getConnectionManager().get());
Run Code Online (Sandbox Code Playgroud)
然后我想把它注入另一个类:
import { injectable, inject } from 'inversify'; …Run Code Online (Sandbox Code Playgroud) 我将 InversifyJS 与 AWS Lambda 结合使用。我使用 Typescript,有控制器、服务和存储库层。在所有层中,我都使用 InversifyJS 的构造函数注入。我的函数正在返回一些静态虚拟文本。所以问题是 - 当我使用 Inversify 进行 DI 时,AWS Cloudwatch 中的内存使用率很高(简单的 hello world 约为 160 MB),但如果没有 Inversify,内存会下降到正常值(约 50 MB)。
希望了解使用 DI 和 AWS Lambda 的一些实际经验。也许有一些替代方法来实现 DI,或者它完全没有被用于无服务器开发?
这个相关问题显示了文档中的示例,但没有解释InversifyJS toFactory与toDynamicValue
toDynamicValue接受工厂功能,而toFactory接受高阶工厂功能。但是toDynamicValue也可以将工厂函数作为值返回。
他们可以达到相同的目的,并且行为如何不同?
如何Bar和Baz在这个例子有什么不同?
container.bind('Bar').toDynamicValue(
context => fooName => context.container.getNamed(Foo, fooName)
)
container.bind('Baz').toFactory(
context => fooName => context.container.getNamed(Foo, fooName)
)
Run Code Online (Sandbox Code Playgroud) 我想使用 Inversify 来删除对 NPM 模块的硬依赖,并将它们作为构造函数参数注入。在我试一试之前,这似乎要简单得多。
事实证明,大多数绝对类型的模块不会费心导出接口,当它们这样做时,它们很少包含代表整个模块的接口。此外,当一个类被导出时,我仍然需要为那个类手动定义一个构造函数接口。
这意味着我必须为几乎每个模块做这样的事情:
import * as ConcreteModule from 'module'
import { ContainerModule } from 'inversify'
export interface ModuleInstance {
// copy a ton of stuff from DefinitelyTyped repo,
// because they didn't export any interfaces
}
export interface ModuleConstructor {
new (...args: any[]): ModuleInstance
}
export const ModuleConstructorSymbol = Symbol('ModuleConstructor')
export const ModuleContainer = new ContainerModule((bind) => {
bind<ModuleConstructor>(ModuleConstructorSymbol).toConstantValue(ConcreteModule)
})
Run Code Online (Sandbox Code Playgroud)
有什么办法可以简化其中的一些吗?注入 NPM 模块的开销太大了,而且 Inversify 文档中没有任何指导。管理您需要的所有不同导入/导出(接口、符号和容器)的名称是一件痛苦的事情,需要提出某种一致的命名方案。似乎没有 TypeScript 支持从模块自动创建接口的某种方式,就没有办法以理智的方式注入 NPM 包。
我想我可以只对模块使用 jest 的 automock 功能,但我真的不喜欢以这样一种方式设计我的代码,即它只能使用特定的测试框架进行单元测试。
如果我可以这样做,这似乎至少可以更容易实现:
import …Run Code Online (Sandbox Code Playgroud) 我有一个使用 inversify 的现有打字稿项目。我已经在我的 TYPES 中定义了一个记录器,TYPES.ILoggger当我直接从我的容器访问记录器时,它可以工作:
import {ILogger} from "./interfaces/ILogger";
import {TYPES} from "./interfaces/TYPES";
import container from "./kernel/inversify.config";
const loggerFromTheContainer: ILogger = container.get<ILogger>(TYPES.ILogger);
loggerFromTheContainer.info("I WILL LOG"); // this works
Run Code Online (Sandbox Code Playgroud)
所以我的设置应该没问题。
我不想直接访问容器,但我想使用属性注入。[InversifyJS' README提供了一个例子:
如果你喜欢它,你可以使用属性注入而不是构造函数注入,这样你就不必声明类构造函数:
Run Code Online (Sandbox Code Playgroud)@injectable() class Ninja implements Warrior { @inject(TYPES.Weapon) private _katana: Weapon; @inject(TYPES.ThrowableWeapon) private _shuriken: ThrowableWeapon; public fight() { return this._katana.hit(); } public sneak() { return this._shuriken.throw(); } }
我试着遵循那个。
然而,当我尝试通过属性注入来注入记录器时,我突然undefined变成了一个记录器,我不知道为什么:
@injectable()
class ShouldHaveLogger {
@inject(TYPES.ILogger) private logger: ILogger;
constructor() {
this.logger.info("Hello World"); // this.logger …Run Code Online (Sandbox Code Playgroud) 我在我的打字稿项目中使用 inversifyJs 进行 DI。使用装饰器 @multiInject 时,我收到错误“发现 serviceIdentifier 不明确匹配”。我正在关注这个示例(https://github.com/inversify/InversifyJS/blob/master/wiki/multi_injection.md)。为什么我会收到此错误?任何帮助将不胜感激。谢谢。
import 'reflect-metadata';
import { Container, multiInject, injectable, } from 'inversify';
interface IWeapon {
name: string;
}
interface INinja {
weapons: IWeapon[],
displayWeapons(): void,
}
@injectable()
class Katana implements IWeapon {
public name = 'Katana';
}
@injectable()
class Shuriken implements IWeapon {
public name = 'Shuriken';
}
@injectable()
class Ninja implements INinja {
public weapons: IWeapon[];
constructor(
@multiInject('Weapon') _weapons: IWeapon[],
) {
this.weapons = _weapons;
}
public displayWeapons = () => …Run Code Online (Sandbox Code Playgroud) 我将 InversifyJS 与绑定和惰性注入装饰器一起使用,并且收到下一个错误:
找不到 serviceIdentifier: Symbol(ClassB) 的匹配绑定
这是代码:
inversify.config.ts
import { Container } from 'inversify';
import getDecorators from 'inversify-inject-decorators';
import { buildProviderModule, provide } from 'inversify-binding-decorators';
import Types from './types';
const container = new Container();
container.bind<MyType>(Types.MyType)
.to(MyType);
const { lazyInject } = getDecorators(container, false);
container.load(buildProviderModule());
export { container, lazyInject, provide };
Run Code Online (Sandbox Code Playgroud)
MyType.ts
import { inject, injectable } from 'inversify';
@injectable()
export class MyType{
constructor(
@inject(Q) private readonly Q: Q,
@inject(W) private readonly W: W,
@inject(E) private readonly E: E) { …Run Code Online (Sandbox Code Playgroud) typescript javascript-import inversifyjs javascript-decorators
inversifyjs ×10
typescript ×9
javascript ×3
asp.net-mvc ×1
aws-lambda ×1
inversify-binding-decorators ×1
node.js ×1
typeorm ×1