首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何根据给定参数在tsyringe容器中注册接口的不同实现

如何根据给定参数在tsyringe容器中注册接口的不同实现
EN

Stack Overflow用户
提问于 2022-11-11 17:32:37
回答 2查看 43关注 0票数 1

我试图找到一种优雅的方法,根据给定的值将接口注入到注射器容器中。(字符串/枚举/文号)

以下是我使用switch..case子句所做的工作:

代码语言:javascript
复制
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); 
}

这种方法的问题是,它不是很优雅,它需要导入所有可能的实现,即使在运行时只需要一个。

有什么更好的解决办法吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-11-13 12:54:50

这是一个要旨,它是我研究DI解决方案的一部分。

显然,我们必须使用predicateawareclassfactory。但是我发现一个更简单的版本,它运行得很好,¯\_(ツ)_/¯

代码语言:javascript
复制
container.register(Tokens.logger, {
  useFactory: () => {
    return process.env.NODE_ENV === "production"
      ? container.resolve(PinoLogger)
      : container.resolve(ConsoleLogger)
  },
})
票数 1
EN

Stack Overflow用户

发布于 2022-11-12 22:10:20

免责声明:作者

这里有一个解决方案,但是在不同的DI框架中。

我认为这是唯一支持异步延迟导入以避免导入运行时不需要的东西的DI解决方案。任何其他DI系统都必须支持async。据我所知,在撰写本报告时,没有其他人这样做。我查过30左右了。

交互式工作演示

代码语言:javascript
复制
  // 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" })
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74406193

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档