feat: support Autowired and JSClass inject
Signed-off-by: MiaoWoo <admin@yumc.pw>
This commit is contained in:
parent
5a9e33e695
commit
17ed9d7d52
@ -25,6 +25,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"inversify": "^5.0.1",
|
"inversify": "^5.0.1",
|
||||||
"inversify-binding-decorators": "^4.0.0"
|
"inversify-binding-decorators": "^4.0.0",
|
||||||
|
"@ccms/nashorn": "^0.7.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
7
packages/container/src/constants.ts
Normal file
7
packages/container/src/constants.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export namespace ioc {
|
||||||
|
export const Autowired = Symbol('Autowired')
|
||||||
|
export const Resource = Symbol('Resource')
|
||||||
|
export const JavaClass = Symbol('JavaClass')
|
||||||
|
export const JavaInstance = Symbol('JavaInstance')
|
||||||
|
export const JavaStaticClass = Symbol('JavaStaticClass')
|
||||||
|
}
|
@ -1,9 +1,9 @@
|
|||||||
import { interfaces, Container } from "inversify";
|
import { interfaces, Container } from "inversify"
|
||||||
|
|
||||||
let _container: Container;
|
let _container: Container
|
||||||
|
|
||||||
const ContainerInstance = Symbol.for("@ccms/ioc:Container");
|
const ContainerInstance = Symbol.for("@ccms/ioc:Container")
|
||||||
const INJECTION = Symbol.for("INJECTION");
|
const INJECTION = Symbol.for("INJECTION")
|
||||||
|
|
||||||
function _proxyGetter(
|
function _proxyGetter(
|
||||||
proto: any,
|
proto: any,
|
||||||
@ -13,17 +13,17 @@ function _proxyGetter(
|
|||||||
) {
|
) {
|
||||||
function getter(this: object) {
|
function getter(this: object) {
|
||||||
if (doCache && !Reflect.hasMetadata(INJECTION, this, key)) {
|
if (doCache && !Reflect.hasMetadata(INJECTION, this, key)) {
|
||||||
Reflect.defineMetadata(INJECTION, resolve(), this, key);
|
Reflect.defineMetadata(INJECTION, resolve(), this, key)
|
||||||
}
|
}
|
||||||
if (Reflect.hasMetadata(INJECTION, this, key)) {
|
if (Reflect.hasMetadata(INJECTION, this, key)) {
|
||||||
return Reflect.getMetadata(INJECTION, this, key);
|
return Reflect.getMetadata(INJECTION, this, key)
|
||||||
} else {
|
} else {
|
||||||
return resolve();
|
return resolve()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setter(this: object, newVal: any) {
|
function setter(this: object, newVal: any) {
|
||||||
Reflect.defineMetadata(INJECTION, newVal, this, key);
|
Reflect.defineMetadata(INJECTION, newVal, this, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.defineProperty(proto, key, {
|
Object.defineProperty(proto, key, {
|
||||||
@ -31,63 +31,63 @@ function _proxyGetter(
|
|||||||
enumerable: true,
|
enumerable: true,
|
||||||
get: getter,
|
get: getter,
|
||||||
set: setter
|
set: setter
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function initContainer(container: Container) {
|
function initContainer(container: Container) {
|
||||||
Reflect.defineMetadata(ContainerInstance, container, Reflect);
|
Reflect.defineMetadata(ContainerInstance, container, Reflect)
|
||||||
_container = container;
|
return _container = container
|
||||||
}
|
}
|
||||||
|
|
||||||
function getContainer(): Container {
|
function getContainer(): Container {
|
||||||
return _container || Reflect.getMetadata(ContainerInstance, Reflect)
|
return _container || initContainer(new Container())
|
||||||
}
|
}
|
||||||
|
|
||||||
function makePropertyInjectDecorator(doCache: boolean) {
|
function makePropertyInjectDecorator(doCache: boolean) {
|
||||||
return function (serviceIdentifier: interfaces.ServiceIdentifier<any>) {
|
return function (serviceIdentifier: interfaces.ServiceIdentifier<any>) {
|
||||||
return function (proto: any, key: string): void {
|
return function (proto: any, key: string): void {
|
||||||
let resolve = () => {
|
let resolve = () => {
|
||||||
return getContainer().get(serviceIdentifier);
|
return getContainer().get(serviceIdentifier)
|
||||||
};
|
}
|
||||||
_proxyGetter(proto, key, resolve, doCache);
|
_proxyGetter(proto, key, resolve, doCache)
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function makePropertyInjectNamedDecorator(doCache: boolean) {
|
function makePropertyInjectNamedDecorator(doCache: boolean) {
|
||||||
return function (serviceIdentifier: interfaces.ServiceIdentifier<any>, named: string) {
|
return function (serviceIdentifier: interfaces.ServiceIdentifier<any>, named: string) {
|
||||||
return function (proto: any, key: string): void {
|
return function (proto: any, key: string): void {
|
||||||
let resolve = () => {
|
let resolve = () => {
|
||||||
return getContainer().getNamed(serviceIdentifier, named);
|
return getContainer().getNamed(serviceIdentifier, named)
|
||||||
};
|
}
|
||||||
_proxyGetter(proto, key, resolve, doCache);
|
_proxyGetter(proto, key, resolve, doCache)
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function makePropertyInjectTaggedDecorator(doCache: boolean) {
|
function makePropertyInjectTaggedDecorator(doCache: boolean) {
|
||||||
return function (serviceIdentifier: interfaces.ServiceIdentifier<any>, key: string, value: any) {
|
return function (serviceIdentifier: interfaces.ServiceIdentifier<any>, key: string, value: any) {
|
||||||
return function (proto: any, propertyName: string): void {
|
return function (proto: any, propertyName: string): void {
|
||||||
let resolve = () => {
|
let resolve = () => {
|
||||||
return getContainer().getTagged(serviceIdentifier, key, value);
|
return getContainer().getTagged(serviceIdentifier, key, value)
|
||||||
};
|
}
|
||||||
_proxyGetter(proto, propertyName, resolve, doCache);
|
_proxyGetter(proto, propertyName, resolve, doCache)
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function makePropertyMultiInjectDecorator(doCache: boolean) {
|
function makePropertyMultiInjectDecorator(doCache: boolean) {
|
||||||
return function (serviceIdentifier: interfaces.ServiceIdentifier<any>) {
|
return function (serviceIdentifier: interfaces.ServiceIdentifier<any>) {
|
||||||
return function (proto: any, key: string): void {
|
return function (proto: any, key: string): void {
|
||||||
let resolve = () => {
|
let resolve = () => {
|
||||||
return getContainer().getAll(serviceIdentifier);
|
return getContainer().getAll(serviceIdentifier)
|
||||||
};
|
}
|
||||||
_proxyGetter(proto, key, resolve, doCache);
|
_proxyGetter(proto, key, resolve, doCache)
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let doCache = true;
|
let doCache = true
|
||||||
|
|
||||||
let lazyInject = makePropertyInjectDecorator(doCache)
|
let lazyInject = makePropertyInjectDecorator(doCache)
|
||||||
let lazyInjectNamed = makePropertyInjectNamedDecorator(doCache)
|
let lazyInjectNamed = makePropertyInjectNamedDecorator(doCache)
|
||||||
@ -102,4 +102,4 @@ export {
|
|||||||
lazyInjectNamed,
|
lazyInjectNamed,
|
||||||
lazyInjectTagged,
|
lazyInjectTagged,
|
||||||
lazyMultiInject
|
lazyMultiInject
|
||||||
};
|
}
|
||||||
|
@ -1,25 +1,91 @@
|
|||||||
import "reflect-metadata";
|
/// <reference types="@ccms/nashorn" />
|
||||||
import { initContainer } from './decorators'
|
|
||||||
import { interfaces, Container } from 'inversify';
|
|
||||||
import { fluentProvide } from 'inversify-binding-decorators';
|
|
||||||
|
|
||||||
const provideNamed = (identifier: interfaces.ServiceIdentifier<any>, name: string) => {
|
import "reflect-metadata"
|
||||||
return fluentProvide(identifier).whenTargetNamed(name).done();
|
import { initContainer, getContainer } from './decorators'
|
||||||
};
|
import { interfaces, Container } from 'inversify'
|
||||||
|
import { fluentProvide } from 'inversify-binding-decorators'
|
||||||
|
import { ioc } from "./constants"
|
||||||
|
|
||||||
const provideSingleton = (identifier: interfaces.ServiceIdentifier<any>) => {
|
/**
|
||||||
return fluentProvide(identifier).inSingletonScope().done();
|
* 注册一个命名对象
|
||||||
};
|
* @param identifier 标识符
|
||||||
|
* @param name 名称
|
||||||
|
*/
|
||||||
|
export const provideNamed = (identifier: interfaces.ServiceIdentifier<any>, name: string) => {
|
||||||
|
return fluentProvide(identifier).whenTargetNamed(name).done()
|
||||||
|
}
|
||||||
|
|
||||||
const DefaultContainer = new Container();
|
/**
|
||||||
initContainer(DefaultContainer);
|
* 注册一个单例对象
|
||||||
|
* @param identifier 标识符
|
||||||
|
*/
|
||||||
|
export const provideSingleton = (identifier: interfaces.ServiceIdentifier<any>) => {
|
||||||
|
return fluentProvide(identifier).inSingletonScope().done()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注册一个单例对象
|
||||||
|
* @param identifier 标识符
|
||||||
|
*/
|
||||||
|
export const provideSingletonNamed = (identifier: interfaces.ServiceIdentifier<any>, name: string) => {
|
||||||
|
return fluentProvide(identifier).inSingletonScope().whenTargetNamed(name).done()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得一个 java.lang.Class
|
||||||
|
* @param className Java全类名
|
||||||
|
*/
|
||||||
|
export const JavaClass = (className: string) => {
|
||||||
|
return function (target: any, propertyKey: string, index?: number) {
|
||||||
|
try { target[propertyKey] = Java.type(className).class; return } catch (error) { }
|
||||||
|
try { target[propertyKey] = base.getClass(className); return } catch (error) { }
|
||||||
|
console.warn('JavaClass Inject target', target, 'propertyKey', propertyKey, 'failed!')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得一个JS的Java类
|
||||||
|
* @param className Java 全类名
|
||||||
|
*/
|
||||||
|
export const JSClass = (className: string) => {
|
||||||
|
return function (target: any, propertyKey: string, index?: number) {
|
||||||
|
try { target[propertyKey] = Java.type(className); return } catch (error) { }
|
||||||
|
try { target[propertyKey] = base.getClass(className).static; return } catch (error) { }
|
||||||
|
console.warn('JSClass Inject target', target, 'propertyKey', propertyKey, 'failed!')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自动注入实例由平台实现
|
||||||
|
* @param className 类名
|
||||||
|
*/
|
||||||
|
export const Autowired = (className?: string | any) => {
|
||||||
|
return function (target: any, propertyKey: string) {
|
||||||
|
target[propertyKey] = getContainer().getNamed(ioc.Autowired, className || propertyKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自动注入资源由平台实现
|
||||||
|
* @param className 类名
|
||||||
|
*/
|
||||||
|
export const Resource = (resourceName?: string | any) => {
|
||||||
|
return function (target: any, propertyKey: string) {
|
||||||
|
target[propertyKey] = getContainer().getNamed(ioc.Resource, resourceName || propertyKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const reduceMetadata = (ctx: interfaces.Context): any => {
|
||||||
|
return ctx.currentRequest.target.metadata.reduce((result, entry, index) => {
|
||||||
|
result[entry.key] = entry.value
|
||||||
|
return result
|
||||||
|
}, {})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DefaultContainer = new Container()
|
||||||
|
initContainer(DefaultContainer)
|
||||||
|
|
||||||
export * from 'inversify'
|
export * from 'inversify'
|
||||||
|
export * from './constants'
|
||||||
export * from './decorators'
|
export * from './decorators'
|
||||||
export * from 'inversify-binding-decorators'
|
export * from 'inversify-binding-decorators'
|
||||||
export {
|
|
||||||
fluentProvide,
|
|
||||||
provideNamed,
|
|
||||||
provideSingleton,
|
|
||||||
DefaultContainer
|
|
||||||
};
|
|
||||||
|
Loading…
Reference in New Issue
Block a user