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

typedi 强大的javascript以及typescript 依赖注入框架的更多相关文章

  1. JavaScript里的依赖注入

    JavaScript里的依赖注入 我喜欢引用这句话,“程序是对复杂性的管理”.计算机世界是一个巨大的抽象建筑群.我们简单的包装一些东西然后发布新工具,周而复始.现在思考下,你所使用的语言包括的一些内建 ...

  2. Ninject是一款.Net平台下的开源依赖注入框架

    Ninject是一款.Net平台下的开源依赖注入框架.按照官方说法,它快如闪电.超级轻量,且充分利用了.Net的最新语法,使用Lambda表达式代替Xml文件完成类型绑定.Ninject结构精巧,功能 ...

  3. Spring.NET依赖注入框架学习--简介

    Spring.NET依赖注入框架学习--Spring.NET简介 概述 Spring.NET是一个应用程序框架,其目的是协助开发人员创建企业级的.NET应用程序.它提供了很多方面的功能,比如依赖注入. ...

  4. .NET Core 中依赖注入框架详解 Autofac

    本文将通过演示一个Console应用程序和一个ASP.NET Core Web应用程序来说明依赖注入框架Autofac是如何使用的 Autofac相比.NET Core原生的注入方式提供了强大的功能, ...

  5. [Android]依赖注入框架google的dagger

    分享一下Android依赖注入框架--Google升级版Dagger2框架 Google的Dagger2是对上一版squareup的Dagger改版,话不多说直接上项目代码. Dagger2源码 Da ...

  6. [Android]依赖注入框架squareup的dagger

    分享一下Android依赖注入框架--Dagger使用 Dagger源码 Dagger1-Demo 希望能给大家的开发带来帮助.

  7. Android Dagger依赖注入框架浅析

    今天接触了Dagger这套android的依赖注入框架(DI框架).感觉跟Spring 的IOC差点儿相同吧.这个框架它的优点是它没有採用反射技术(Spring是用反射的),而是用预编译技术.因为基于 ...

  8. 依赖注入及AOP简述(四)——“好莱坞原则”和依赖注入框架简介 .

    3.2.    “好莱坞原则” 看了前面关于依赖注入概念的描述,我们来提炼出依赖注入的核心思想.如果说传统的组件间耦合方式,例如new.工厂模式等,是一种由开发者主动去构建依赖对象的话,那么依赖注入模 ...

  9. Dora.Interception,为.NET Core度身打造的AOP框架 [4]:与依赖注入框架的无缝集成

    Dora.Interception最初的定位就是专门针对.NET Core的AOP框架,所以在整个迭代过程中我大部分是在做减法.对于.NET Core程序开发来说,依赖注入已经成为无处不在并且“深入骨 ...

随机推荐

  1. 可落地的DDD(4)-如何利用DDD进行微服务的划分(2)

    摘要 在前面一篇介绍了如何通过DDD的思想,来调整单体服务内的工程结构,为微服务的拆分做准备.同时介绍了我们在进行微服务拆分的时候踩过的一些坑. 这篇介绍下我们最终的方案,不一定对,欢迎留言讨论. 微 ...

  2. lightGBM gpu环境配置

    推荐先看一手官方的Installation Guide.我用的是ubuntu 16.04,一些要求如下图: 主要是OpenCL以及libboost两个环境的要求. (1) OpenCL的安装.我这里之 ...

  3. JavaScript入门(三)

    JavaScript入门篇—JSONP的应用 什么是JSONP 个人理解:将服务器端返回的json数据封装成JavaScript对象,非正式传输协议. JSONP解决了什么问题 Ajax不支持跨域请求 ...

  4. Smack Extensions用户手册

    Smack Extensions用户手册 XMPP协议包括基本协议和许多可选扩展,通常记录为“XEP”.Smack为核心XMPP协议提供了org.jivesoftware.smack包,为许多协议扩展 ...

  5. Java的Annnotation (注解)

    注解是什么呢? 其实就像商场的商品上都贴有自己的标签一样,它提供了关于这个商品的许多额外信息.你可以根据这些信息对其进行附加的处理. (Java的语法糖果然比较差劲), 这个name()方法太累赘了, ...

  6. java 枚举示例

    public enum YNEnum { N(0,"否"), Y(1,"是"); private int code; private String name; ...

  7. Springboot - java.lang.IllegalStateException: Failed to load property source from location 'classpath:/application.yml'

    Caused by: org.yaml.snakeyaml.scanner.ScannerException: while scanning a simple key in 'reader', lin ...

  8. layui 表格中实现照片预览,点击查看原图

    人员表格中实现照片预览,并且可点击放大.查看原图 <table id="dutyInfoTable" class="layui-hide">< ...

  9. Java 之 线程池

    一.线程池思想概述 如果使用线程的时候就去创建一个线程,这样实现起来非常简便,但是会出现一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低 ...

  10. CSS 案例

    一.滑动门案例 二.小黄人案例 三.圣杯布局&双飞翼布局