我试图找到一种优雅的方法,根据给定的值将接口注入到注射器容器中。(字符串/枚举/文号)
以下是我使用switch..case子句所做的工作:
interface IColor{
someMethod():void;
readonly someInfo:any;
}
class Blue implements IColor{
constructor() {
}
someMethod() {
console.log('I am blue');
}
}
class Red implements IColor{
constructor() {
}
someMethod() {
console.log('I am red');
}
}
@injectable()
class SurfaceService{
constructor(@inject('IColor')readonly color:IColor) {
}
}
// main
import {container} from "tsyringe";
const mainFunction = (someData:{colorinfo:string}) =>{
switch (someData.colorinfo){
case 'RED':
container.register("IColor", {useClass: Red});
break;
case 'Blue':
container.register("IColor", {useClass: Blue});
break;
}
const service = container.resolve(SurfaceService);
}这种方法的问题是,它不是很优雅,它需要导入所有可能的实现,即使在运行时只需要一个。
有什么更好的解决办法吗?
发布于 2022-11-13 12:54:50
这是一个要旨,它是我研究DI解决方案的一部分。
显然,我们必须使用predicateawareclassfactory。但是我发现一个更简单的版本,它运行得很好,¯\_(ツ)_/¯
container.register(Tokens.logger, {
useFactory: () => {
return process.env.NODE_ENV === "production"
? container.resolve(PinoLogger)
: container.resolve(ConsoleLogger)
},
})发布于 2022-11-12 22:10:20
免责声明:作者
这里有一个解决方案,但是在不同的DI框架中。
我认为这是唯一支持异步延迟导入以避免导入运行时不需要的东西的DI解决方案。任何其他DI系统都必须支持async。据我所知,在撰写本报告时,没有其他人这样做。我查过30左右了。
交互式工作演示

// Business logic
interface IColor {
someMethod(): void
// readonly someInfo:any;
}
export class Blue implements IColor {
constructor() {}
someMethod() {
console.log("I am blue")
}
}
export class Red implements IColor {
constructor() {}
someMethod() {
console.log("I am red")
}
}
export class SurfaceService {
constructor(readonly color: IColor) {}
}
// main
export const container = createContainer()
.add(() => ({
blue: async () => {
const { Blue } = await import("./_0.business-logic")
return new Blue()
},
red: async () => {
const { Red } = await import("./_0.business-logic")
return new Red()
},
}))
.add((ctx) => ({
surfaceService: async () => {
// @ts-ignore
if (process?.env?.NODE_ENV === "production") {
return await ctx.blue
} else {
return await ctx.red
}
},
getCustomColor: () => async (someData: { colorInfo: string }) => {
if (someData.colorInfo === "RED") {
return await ctx.red
}
return await ctx.blue
},
}))
// usage
const colorByEnv = await container.items.surfaceService // Blue or Red
const red = await container.items.getCustomColor({ colorInfo: "RED" })https://stackoverflow.com/questions/74406193
复制相似问题