• 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

  • 相关阅读:
    Sum Root to Leaf Numbers 解答
    459. Repeated Substring Pattern
    71. Simplify Path
    89. Gray Code
    73. Set Matrix Zeroes
    297. Serialize and Deserialize Binary Tree
    449. Serialize and Deserialize BST
    451. Sort Characters By Frequency
    165. Compare Version Numbers
    447. Number of Boomerangs
  • 原文地址:https://www.cnblogs.com/rongfengliang/p/11637595.html
Copyright © 2020-2023  润新知