Inversify 的分层 DI 如何工作?
How does Inversify's hierarchical DI work?
inversify-express-utils 自述文件包含以下内容 example on request-scoped services。
我正在尝试为 Koa 应用程序实现类似的东西,但是,我很难理解此示例中的分层 DI 是如何工作的。
import { inject, injectable } from "inversify";
import { BaseHttpController, BaseMiddleware, controller, httpGet } from "inversify-express-utils";
import * as express from "express";
const TYPES = {
TraceId: Symbol.for("TraceIdValue"),
TracingMiddleware: Symbol.for("TracingMiddleware"),
Service: Symbol.for("Service"),
};
@injectable()
class TracingMiddleware extends BaseMiddleware {
public handler(
req: express.Request,
res: express.Response,
next: express.NextFunction
) {
this.bind<string>(TYPES.TraceIdValue)
.toConstantValue(`${ req.header('X-Trace-Id') }`);
next();
}
}
@controller("/")
class TracingTestController extends BaseHttpController {
constructor(@inject(TYPES.Service) private readonly service: Service) {
super();
}
@httpGet(
"/",
TYPES.TracingMiddleware
)
public getTest() {
return this.service.doSomethingThatRequiresTheTraceID();
}
}
@injectable()
class Service {
constructor(@inject(TYPES.TraceIdValue) private readonly traceID: string) {
}
public doSomethingThatRequiresTheTraceID() {
// ...
}
}
通过阅读文档和代码,我了解到 each Express request handler has a HttpContext
attached to it, which in turn has a child DI container attached。
该示例表明 Service
class 的 traceID
依赖项已从 Express 请求中附加到 httpContext
的子容器中解析。
但是,我不明白如何确保 traceID
是从子容器而不是父容器或根容器解析的?
httpContext.container.getNamed<any>(TYPE.Controller, controllerName)[key](...args)
这里是从子容器解析控制器的地方,因此 traceId 依赖项也是从子容器解析的。
inversify-express-utils 自述文件包含以下内容 example on request-scoped services。
我正在尝试为 Koa 应用程序实现类似的东西,但是,我很难理解此示例中的分层 DI 是如何工作的。
import { inject, injectable } from "inversify";
import { BaseHttpController, BaseMiddleware, controller, httpGet } from "inversify-express-utils";
import * as express from "express";
const TYPES = {
TraceId: Symbol.for("TraceIdValue"),
TracingMiddleware: Symbol.for("TracingMiddleware"),
Service: Symbol.for("Service"),
};
@injectable()
class TracingMiddleware extends BaseMiddleware {
public handler(
req: express.Request,
res: express.Response,
next: express.NextFunction
) {
this.bind<string>(TYPES.TraceIdValue)
.toConstantValue(`${ req.header('X-Trace-Id') }`);
next();
}
}
@controller("/")
class TracingTestController extends BaseHttpController {
constructor(@inject(TYPES.Service) private readonly service: Service) {
super();
}
@httpGet(
"/",
TYPES.TracingMiddleware
)
public getTest() {
return this.service.doSomethingThatRequiresTheTraceID();
}
}
@injectable()
class Service {
constructor(@inject(TYPES.TraceIdValue) private readonly traceID: string) {
}
public doSomethingThatRequiresTheTraceID() {
// ...
}
}
通过阅读文档和代码,我了解到 each Express request handler has a HttpContext
attached to it, which in turn has a child DI container attached。
该示例表明 Service
class 的 traceID
依赖项已从 Express 请求中附加到 httpContext
的子容器中解析。
但是,我不明白如何确保 traceID
是从子容器而不是父容器或根容器解析的?
httpContext.container.getNamed<any>(TYPE.Controller, controllerName)[key](...args)
这里是从子容器解析控制器的地方,因此 traceId 依赖项也是从子容器解析的。