feat: support Autowired and JSClass inject
Signed-off-by: MiaoWoo <admin@yumc.pw>
This commit is contained in:
		
							
								
								
									
										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 INJECTION = Symbol.for("INJECTION");
 | 
			
		||||
const ContainerInstance = Symbol.for("@ccms/ioc:Container")
 | 
			
		||||
const INJECTION = Symbol.for("INJECTION")
 | 
			
		||||
 | 
			
		||||
function _proxyGetter(
 | 
			
		||||
    proto: any,
 | 
			
		||||
@@ -13,17 +13,17 @@ function _proxyGetter(
 | 
			
		||||
) {
 | 
			
		||||
    function getter(this: object) {
 | 
			
		||||
        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)) {
 | 
			
		||||
            return Reflect.getMetadata(INJECTION, this, key);
 | 
			
		||||
            return Reflect.getMetadata(INJECTION, this, key)
 | 
			
		||||
        } else {
 | 
			
		||||
            return resolve();
 | 
			
		||||
            return resolve()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function setter(this: object, newVal: any) {
 | 
			
		||||
        Reflect.defineMetadata(INJECTION, newVal, this, key);
 | 
			
		||||
        Reflect.defineMetadata(INJECTION, newVal, this, key)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Object.defineProperty(proto, key, {
 | 
			
		||||
@@ -31,63 +31,63 @@ function _proxyGetter(
 | 
			
		||||
        enumerable: true,
 | 
			
		||||
        get: getter,
 | 
			
		||||
        set: setter
 | 
			
		||||
    });
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function initContainer(container: Container) {
 | 
			
		||||
    Reflect.defineMetadata(ContainerInstance, container, Reflect);
 | 
			
		||||
    _container = container;
 | 
			
		||||
    Reflect.defineMetadata(ContainerInstance, container, Reflect)
 | 
			
		||||
    return _container = container
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getContainer(): Container {
 | 
			
		||||
    return _container || Reflect.getMetadata(ContainerInstance, Reflect)
 | 
			
		||||
    return _container || initContainer(new Container())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function makePropertyInjectDecorator(doCache: boolean) {
 | 
			
		||||
    return function(serviceIdentifier: interfaces.ServiceIdentifier<any>) {
 | 
			
		||||
        return function(proto: any, key: string): void {
 | 
			
		||||
    return function (serviceIdentifier: interfaces.ServiceIdentifier<any>) {
 | 
			
		||||
        return function (proto: any, key: string): void {
 | 
			
		||||
            let resolve = () => {
 | 
			
		||||
                return getContainer().get(serviceIdentifier);
 | 
			
		||||
            };
 | 
			
		||||
            _proxyGetter(proto, key, resolve, doCache);
 | 
			
		||||
        };
 | 
			
		||||
    };
 | 
			
		||||
                return getContainer().get(serviceIdentifier)
 | 
			
		||||
            }
 | 
			
		||||
            _proxyGetter(proto, key, resolve, doCache)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function makePropertyInjectNamedDecorator(doCache: boolean) {
 | 
			
		||||
    return function(serviceIdentifier: interfaces.ServiceIdentifier<any>, named: string) {
 | 
			
		||||
        return function(proto: any, key: string): void {
 | 
			
		||||
    return function (serviceIdentifier: interfaces.ServiceIdentifier<any>, named: string) {
 | 
			
		||||
        return function (proto: any, key: string): void {
 | 
			
		||||
            let resolve = () => {
 | 
			
		||||
                return getContainer().getNamed(serviceIdentifier, named);
 | 
			
		||||
            };
 | 
			
		||||
            _proxyGetter(proto, key, resolve, doCache);
 | 
			
		||||
        };
 | 
			
		||||
    };
 | 
			
		||||
                return getContainer().getNamed(serviceIdentifier, named)
 | 
			
		||||
            }
 | 
			
		||||
            _proxyGetter(proto, key, resolve, doCache)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function makePropertyInjectTaggedDecorator(doCache: boolean) {
 | 
			
		||||
    return function(serviceIdentifier: interfaces.ServiceIdentifier<any>, key: string, value: any) {
 | 
			
		||||
        return function(proto: any, propertyName: string): void {
 | 
			
		||||
    return function (serviceIdentifier: interfaces.ServiceIdentifier<any>, key: string, value: any) {
 | 
			
		||||
        return function (proto: any, propertyName: string): void {
 | 
			
		||||
            let resolve = () => {
 | 
			
		||||
                return getContainer().getTagged(serviceIdentifier, key, value);
 | 
			
		||||
            };
 | 
			
		||||
            _proxyGetter(proto, propertyName, resolve, doCache);
 | 
			
		||||
        };
 | 
			
		||||
    };
 | 
			
		||||
                return getContainer().getTagged(serviceIdentifier, key, value)
 | 
			
		||||
            }
 | 
			
		||||
            _proxyGetter(proto, propertyName, resolve, doCache)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function makePropertyMultiInjectDecorator(doCache: boolean) {
 | 
			
		||||
    return function(serviceIdentifier: interfaces.ServiceIdentifier<any>) {
 | 
			
		||||
        return function(proto: any, key: string): void {
 | 
			
		||||
    return function (serviceIdentifier: interfaces.ServiceIdentifier<any>) {
 | 
			
		||||
        return function (proto: any, key: string): void {
 | 
			
		||||
            let resolve = () => {
 | 
			
		||||
                return getContainer().getAll(serviceIdentifier);
 | 
			
		||||
            };
 | 
			
		||||
            _proxyGetter(proto, key, resolve, doCache);
 | 
			
		||||
        };
 | 
			
		||||
    };
 | 
			
		||||
                return getContainer().getAll(serviceIdentifier)
 | 
			
		||||
            }
 | 
			
		||||
            _proxyGetter(proto, key, resolve, doCache)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
let doCache = true;
 | 
			
		||||
let doCache = true
 | 
			
		||||
 | 
			
		||||
let lazyInject = makePropertyInjectDecorator(doCache)
 | 
			
		||||
let lazyInjectNamed = makePropertyInjectNamedDecorator(doCache)
 | 
			
		||||
@@ -102,4 +102,4 @@ export {
 | 
			
		||||
    lazyInjectNamed,
 | 
			
		||||
    lazyInjectTagged,
 | 
			
		||||
    lazyMultiInject
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,25 +1,91 @@
 | 
			
		||||
import "reflect-metadata";
 | 
			
		||||
import { initContainer } from './decorators'
 | 
			
		||||
import { interfaces, Container } from 'inversify';
 | 
			
		||||
import { fluentProvide } from 'inversify-binding-decorators';
 | 
			
		||||
/// <reference types="@ccms/nashorn" />
 | 
			
		||||
 | 
			
		||||
const provideNamed = (identifier: interfaces.ServiceIdentifier<any>, name: string) => {
 | 
			
		||||
    return fluentProvide(identifier).whenTargetNamed(name).done();
 | 
			
		||||
};
 | 
			
		||||
import "reflect-metadata"
 | 
			
		||||
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 './constants'
 | 
			
		||||
export * from './decorators'
 | 
			
		||||
export * from 'inversify-binding-decorators'
 | 
			
		||||
export {
 | 
			
		||||
    fluentProvide,
 | 
			
		||||
    provideNamed,
 | 
			
		||||
    provideSingleton,
 | 
			
		||||
    DefaultContainer
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user