typedi 强大的javascript以及typescript 依赖注入框架

typedi 是typestack团队提供的依赖注入解决方案,对于typescript 我们可以使用注解的开发方式,官方的文档也比较详细

javascript 使用

  • 基于函数的服务注入
var Service = require("typedi").Service;
var Container = require("typedi").Container;
var PostRepository = Service(() => ({
    getName() {
        return "hello from post repository";
    }
}));
var PostManager = Service(() => ({
    getId() {
        return "some post id";
    }
}));
class PostQueryBuilder {
    build() {
        return "SUPER * QUERY";
    }
}
var PostController = Service([
    PostManager,
    PostRepository,
    PostQueryBuilder
], (manager, repository, queryBuilder) => {
    return {
        id: manager.getId(),
        name: repository.getName(),
        query: queryBuilder.build()
    };
});
var postController = Container.get(PostController);
console.log(postController);
 
 
  • 基于名称的注入
var Container = require("typedi").Container;
class BeanFactory {
    constructor(container){}
    create() {
      console.log("BeanFactory")
    }
}
class SugarFactor {
    constructor(container){}
    create() {
        console.log("SugarFactory")
    }
}
class WaterFactory{
    constructor(container){}
    create() {
        console.log("WaterFactory")
    }
}
class CoffeeMaker {
    constructor(container) {
        this.beanFactory = container.get("bean.factory");
        this.sugarFactory = container.get("sugar.factory");
        this.waterFactory = container.get("water.factory");
    }
    make() {
        this.beanFactory.create();
        this.sugarFactory.create();
        this.waterFactory.create();
    }
}
Container.set("bean.factory", new BeanFactory(Container));
Container.set("sugar.factory", new SugarFactory(Container));
Container.set("water.factory", new WaterFactory(Container));
Container.set("coffee.maker", new CoffeeMaker(Container));
var coffeeMaker = Container.get("coffee.maker");
coffeeMaker.make();
 
 

typescript 使用

对于typescript 的使用我们可以利用ts提供的强大类型能力,以及注解可以编写强大的功能

  • 简单service注解
    项目结构
 
ts
└── service
    ├── SomeClass.ts
    └── demo.ts
 
 

demo.ts


import {Container} from "typedi";
import {SomeClass } from "./SomeClass"
let someClass = Container.get(SomeClass);
someClass.someMethod();
 
 

SomeClass.ts


import "reflect-metadata";
import {Service} from "typedi";
@Service()
class SomeClass {
    someMethod() {
        console.log("call from service")
    }
}
export default SomeClass
export {
    SomeClass
}
 
 
  • 基于属性的注入
import "reflect-metadata"
import {Container, Inject, Service} from "typedi";
@Service()
class BeanFactory {
    create() {
        console.log("BeanFactory")
    }
}
@Service()
class SugarFactory {
    create() {
        console.log("SugarFactory")
    }
}
@Service()
class WaterFactory {
    create() {
        console.log("WaterFactory")
    }
}
@Service()
class CoffeeMaker {
    @Inject()
    beanFactory: BeanFactory;
    @Inject()
    sugarFactory: SugarFactory;
    @Inject()
    waterFactory: WaterFactory;
    make() {
        this.beanFactory.create();
        this.sugarFactory.create();
        this.waterFactory.create();
    }
}
let coffeeMaker = Container.get(CoffeeMaker);
coffeeMaker.make();
 
 
  • 基于服务名的注入
import "reflect-metadata"
import {Container, Service, Inject} from "typedi";
interface Factory {
    create(): void;
}
@Service("bean.factory")
class BeanFactory implements Factory {
    create() {
        console.log("BeanFactory")
    }
}
@Service("sugar.factory")
class SugarFactory implements Factory {
    create() {
        console.log("SugarFactory")
    }
}
@Service("water.factory")
class WaterFactory implements Factory {
    create() {
        console.log("WaterFactory")
    }
}
@Service("coffee.maker")
class CoffeeMaker {
    beanFactory: Factory;
    sugarFactory: Factory;
    @Inject("water.factory")
    waterFactory: Factory;
    constructor(@Inject("bean.factory") beanFactory: BeanFactory,
                @Inject("sugar.factory") sugarFactory: SugarFactory) {
        this.beanFactory = beanFactory;
        this.sugarFactory = sugarFactory;
    }
    make() {
        this.beanFactory.create();
        this.sugarFactory.create();
        this.waterFactory.create();
    }
}
let coffeeMaker = Container.get<CoffeeMaker>("coffee.maker");
coffeeMaker.make();
 
 
  • 循环依赖的处理
    对于循环依赖我们需要指定类型,如下:
 
// Car.ts
@Service()
export class Car {
    @Inject()
    engine: Engine;
}
// Engine.ts
@Service()
export class Engine {
    @Inject()
    car: Car;
}
应该为:
// Car.ts
@Service()
export class Car {
    @Inject(type => Engine)
    engine: Engine;
}
// Engine.ts
@Service()
export class Engine {
    @Inject(type => Car)
    car: Car;
}
 
 
  • 注入继承
// Car.ts
@Service()
export abstract class Car {
    @Inject()
    engine: Engine;
}
// Engine.ts
@Service()
export class Bus extends Car {
    // you can call this.engine in this class
}
 
 
  • 服务组
    方便组合依赖的服务
 
// Factory.ts
import "reflect-metadata"
import {Container, Service,Token} from "typedi";
export interface Factory {
    create(): any;
}
// FactoryToken.ts
export const FactoryToken = new Token<Factory>("factories");
// BeanFactory.ts
@Service({ id: FactoryToken, multiple: true })
export class BeanFactory implements Factory {
    create() {
        console.log("bean created");
    }
}
// SugarFactory.ts
@Service({ id: FactoryToken, multiple: true })
export class SugarFactory implements Factory {
    create() {
        console.log("sugar created");
    }
}
// WaterFactory.ts
@Service({ id: FactoryToken, multiple: true })
export class WaterFactory implements Factory {
    create() {
        console.log("water created");
    }
}
// app.ts
// now you can get all factories in a single array
Container.import([
    BeanFactory,
    SugarFactory,
    WaterFactory,
]);
const factories = Container.getMany(FactoryToken); // factories is Factory[]
factories.forEach(factory => factory.create());
 

说明

typedi 功能还是很强大,是web开发中的一个利器

参考资料

https://github.com/typestack/typedi
https://github.com/rongfengliang/typedi-learning

posted on   荣锋亮  阅读(3829)  评论(0编辑  收藏  举报

编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
历史上的今天:
2018-10-08 jaeger 使用ElasticSearch 作为后端存储
2018-10-08 nginx-opentracing 简单使用
2017-10-08 openfaas 架构介绍
2017-10-08 openfaas 简单试用
2017-10-08 openfaas cli 安装
2017-10-08 openfaas 安装(docker swarm 模式)
2017-10-08 openfaas 了解

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示