From 5bf2335c0ff0f9cee252db291a84626926d66f22 Mon Sep 17 00:00:00 2001 From: imeepos <1037483576@qq.com> Date: Thu, 25 Apr 2019 14:33:26 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4injector=E6=94=AF=E6=8C=81Mod?= =?UTF-8?q?uleWithProviders?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker-compose.yml | 2 +- package.json | 1 + packages/nger-core/lib/decorators/ngModule.ts | 102 ++++++++++-------- packages/nger-core/lib/orm/typeorm.ts | 3 +- packages/nger-module-typeorm/README.md | 33 ++++-- readme.md | 2 +- src/server.ts | 23 +++- src/typeorm/index.ts | 9 +- 8 files changed, 119 insertions(+), 56 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index f91fa5b..9a064c9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -22,7 +22,7 @@ services: - 0.0.0.0:3306:3306 environment: MYSQL_ROOT_PASSWORD: 123456 - MYSQL_DATABASE: test + MYSQL_DATABASE: nger volumes: - ./data/mysql:/var/lib/mysql - ./config/mysql/my.conf:/etc/mysql/my.conf diff --git a/package.json b/package.json index c885e33..96e9eb8 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "dependency-graph": "^0.8.0", "fs-extra": "^7.0.1", "gulp": "^4.0.1", + "mysql": "^2.17.1", "reflect-metadata": "^0.1.13", "rxjs": "^6.4.0", "shelljs": "^0.8.3", diff --git a/packages/nger-core/lib/decorators/ngModule.ts b/packages/nger-core/lib/decorators/ngModule.ts index de8e72e..8527229 100644 --- a/packages/nger-core/lib/decorators/ngModule.ts +++ b/packages/nger-core/lib/decorators/ngModule.ts @@ -1,4 +1,4 @@ -import { makeDecorator, ClassContext, ClassAst, TypeContext, ConstructorContext } from 'ims-decorator'; +import { makeDecorator, ClassContext, ClassAst, TypeContext, ConstructorContext, isType } from 'ims-decorator'; export const NgModuleMetadataKey = 'NgModuleMetadataKey'; import { InjectConstructorAst, InjectMetadataKey, InjectPropertyAst } from './inject' import { Provider, Type, ModuleWithProviders, SchemaMetadata, Injector } from 'nger-di'; @@ -10,13 +10,13 @@ import { SelfConstructorAst } from './self'; import { OptionalConstructorAst } from './optional'; export interface NgModuleOptions { providers?: Provider[]; - declarations?: Array | any[]>; - imports?: Array | ModuleWithProviders<{}> | any[]>; - exports?: Array | any[]>; - entryComponents?: Array | any[]>; + declarations?: Array>; + imports?: Array | ModuleWithProviders<{}>>; + exports?: Array>; + entryComponents?: Array>; // 这里是启动组件 也就是首页 前端有用 - bootstrap?: Array | any[]>; - schemas?: Array; + bootstrap?: Array>; + schemas?: Array; id?: string; jit?: true; } @@ -98,6 +98,22 @@ export class NgModuleClassAst extends ClassContext { if (def.exports) this.exports = this.forEachObjectToTypeContent(def.exports); if (def.entryComponents) this.entryComponents = this.forEachObjectToTypeContent(def.entryComponents); if (def.bootstrap) this.bootstrap = this.forEachObjectToTypeContent(def.bootstrap); + if (def.imports) { + def.imports.map(imp => { + if (isType(imp)) { + // type + return this.context.visitType(imp); + } else { + // ModuleWithProviders + const { ngModule, providers } = imp as ModuleWithProviders + const context = this.context.visitType(ngModule); + if (context && providers) { + providers.map(pro => this.handlerProvider(context.injector, pro)); + } + return context; + } + }) + } if (def.imports) this._imports = this.forEachObjectToTypeContent(def.imports); const injector = this.context.typeContext.injector; if (def.exports) { @@ -126,41 +142,7 @@ export class NgModuleClassAst extends ClassContext { }); // 处理provider if (def.providers) { - def.providers.map(pro => { - if (isTypeProvider(pro)) { - // 这里必须有上下级关系,保留 - const ctx = this.context.visitType(pro); - let deps: any[] = []; - if (ctx) { - deps = handlerTypeContextToParams(ctx) - setAppInitializer(injector, ctx) - } - const proProvider: FactoryProvider = { - provide: pro, - useFactory: (...params: any) => new pro(...params), - deps: deps, - multi: false - } - injector.setStatic([proProvider]); - injector.setExport(pro); - } else if (isClassProvider(pro)) { - const ctx = this.context.typeContext.visitor.visitType(pro); - let deps: any[] = []; - if (ctx) { - deps = handlerTypeContextToParams(ctx) - setAppInitializer(injector, ctx) - } - const proProvider: StaticClassProvider = { - ...pro, - deps: deps - } - injector.setStatic([proProvider]); - injector.setExport(pro.provide); - } else { - injector.setStatic([pro]); - injector.setExport(pro.provide); - } - }); + def.providers.map(pro => this.handlerProvider(injector, pro)); } // 当前ngModule注入 const typeContext = this.context.typeContext; @@ -183,6 +165,42 @@ export class NgModuleClassAst extends ClassContext { // 处理属性inject injector.debug(); } + + handlerProvider(injector: Injector, pro: Provider) { + if (isTypeProvider(pro)) { + // 这里必须有上下级关系,保留 + const ctx = this.context.visitType(pro); + let deps: any[] = []; + if (ctx) { + deps = handlerTypeContextToParams(ctx) + setAppInitializer(injector, ctx) + } + const proProvider: FactoryProvider = { + provide: pro, + useFactory: (...params: any) => new pro(...params), + deps: deps, + multi: false + } + injector.setStatic([proProvider]); + injector.setExport(pro); + } else if (isClassProvider(pro)) { + const ctx = this.context.typeContext.visitor.visitType(pro); + let deps: any[] = []; + if (ctx) { + deps = handlerTypeContextToParams(ctx) + setAppInitializer(injector, ctx) + } + const proProvider: StaticClassProvider = { + ...pro, + deps: deps + } + injector.setStatic([proProvider]); + injector.setExport(pro.provide); + } else { + injector.setStatic([pro]); + injector.setExport(pro.provide); + } + } } export function isNgModuleClassAst(ast: ClassAst): ast is ClassAst { return ast.metadataKey === NgModuleMetadataKey; diff --git a/packages/nger-core/lib/orm/typeorm.ts b/packages/nger-core/lib/orm/typeorm.ts index 2e01d9f..b9a0a77 100644 --- a/packages/nger-core/lib/orm/typeorm.ts +++ b/packages/nger-core/lib/orm/typeorm.ts @@ -1,4 +1,4 @@ -import { ClassAst, ClassContext, TypeContext } from 'ims-decorator'; +import { ClassAst, ClassContext, TypeContext, makeDecorator } from 'ims-decorator'; export interface TypeormOptions { /** * 表 @@ -14,6 +14,7 @@ export interface TypeormOptions { subscribers?: any[] | object; } export const TypeormMetadataKey = 'TypeormMetadataKey'; +export const Typeorm = makeDecorator(TypeormMetadataKey) export function isTypeormClassAst(val: ClassAst): val is ClassAst { return val.metadataKey === TypeormMetadataKey; } diff --git a/packages/nger-module-typeorm/README.md b/packages/nger-module-typeorm/README.md index c71b29b..1b58fa4 100644 --- a/packages/nger-module-typeorm/README.md +++ b/packages/nger-module-typeorm/README.md @@ -1,11 +1,28 @@ # `nger-module-typeorm` -> TODO: description +> 使用typeorm -## Usage - -``` -const ngerModuleTypeorm = require('nger-module-typeorm'); - -// TODO: DEMONSTRATE API -``` +## use +```ts +import {NgerModuleTypeorm} from 'nger-module-typeorm'; +@NgModule({ + imports: [NgerModuleTypeorm], + providers: [{ + provide: TypeormToken, + useValue: ImsDemoTypeorm, + multi: true + },{ + provide: TypeormOptionsToken, + useValue: { + type: 'mysql', + username: 'root', + password: '123456', + host: 'localhost', + port: 4200, + database: 'nger', + name: 'nger' + } + }] +}) +export class ImsDemo{} +``` \ No newline at end of file diff --git a/readme.md b/readme.md index 6ae8312..6cfde6b 100644 --- a/readme.md +++ b/readme.md @@ -2,7 +2,7 @@

用ng自由组合开发小程序

-> 项目名称意义,用ng的人!I am a nger! +> 项目名称意义,用ng的人!I am a nger! Warning!Warning!Warning! 这不是一个前端项目。 vue、react相继都有了小程序的开发框架,作为一个nger,也该为社区做点事情了! 很遗憾,由于ng和小程序的差异性,我们暂时没打算直接把ng项目转换成小程序,而是用ng的一套思想(`依赖注入`、`装饰器`等)来规范开发小程序!以达到一套代码多平台运行。 diff --git a/src/server.ts b/src/server.ts index e93ed8c..252dba9 100644 --- a/src/server.ts +++ b/src/server.ts @@ -1,15 +1,34 @@ -import { NgModule, OnInit, Inject, OnError } from 'nger-core'; +import { NgModule, OnInit, Inject, OnError, TypeormToken, TypeormOptionsToken } from 'nger-core'; import { HomeController, UserController } from './inc'; import { NgerModulePm2 } from 'nger-module-pm2'; import { Logger } from 'nger-logger'; import { NgerModuleTypeorm } from 'nger-module-typeorm' +import { NgerRunnerTypeorm } from './typeorm' /** api服务 */ @NgModule({ declarations: [ HomeController, UserController ], - providers: [], + providers: [ + { + provide: TypeormToken, + useValue: NgerRunnerTypeorm, + multi: true + }, + { + provide: TypeormOptionsToken, + useValue: { + type: 'mysql', + username: 'root', + password: '123456', + host: 'localhost', + port: 3306, + database: 'nger', + name: 'nger' + } + } + ], imports: [ NgerModulePm2, NgerModuleTypeorm diff --git a/src/typeorm/index.ts b/src/typeorm/index.ts index 11f8bd1..ba5f10a 100644 --- a/src/typeorm/index.ts +++ b/src/typeorm/index.ts @@ -1 +1,8 @@ -export * from './entities' \ No newline at end of file +export * from './entities' +import * as entities from './entities' +import { Typeorm } from 'nger-core'; + +@Typeorm({ + entities: entities +}) +export class NgerRunnerTypeorm { } \ No newline at end of file