如何解决tsyringe container.resolve 在自定义装饰器中创建一个新的调用实例
我正在尝试为 tsyringe 创建一个自定义装饰器以通过属性注入。
我的代码:
import '@abraham/reflection';
import {container} from 'tsyringe';
/**
* Inject class through property
*
* @param targetClass
* @returns PropertyDecorator
*/
export const inject = (targetClass: new (...args: any[]) => any): PropertyDecorator => {
if (!targetClass || targetClass === undefined) {
throw new Error(`${targetClass} class is undefined`);
}
return (target: any,propertyKey: string | symbol): PropertyDecorator => {
return Object.defineProperty(target,propertyKey,{
get: () => container.resolve((targetClass))
});
};
};
服务
import { injectable } from 'tsyringe';
@injectable()
export class Test {
constructor() {
console.log('hi from test');
}
a(): void {
console.log('a');
}
b(): void {
console.log('b');
}
}
调用类
import React,{ ReactElement } from 'react';
import Head from 'next/head';
import { Test } from '../_service/test.service';
import { inject } from '../decorators/inject';
/**
* @class Home
*/
export default class Home extends React.Component {
@inject(Test)
private readonly test!: Test;
/**
* Render Home
*
* @returns ReactElement<any>
*/
render(): ReactElement<any> {
this.test.a();
this.test.b();
return (
<div>
<Head>
<title>home</title>
</Head>
<main>
<p>test</p>
</main>
</div>
);
}
}
控制台输出
hi from test
a
hi from test
b
当前行为:每次调用注入类的方法时,都会再次调用构造函数。所以这意味着我的类在每次新调用时都会进行新的初始化。
当我使用以下代码时,一切似乎都在工作
import React,{ ReactElement } from 'react';
import Head from 'next/head';
import { Test } from '../_service/test.service';
import { container } from 'tsyringe';
/**
* @class Home
*/
export default class Home extends React.Component {
private readonly test: Test = container.resolve(Test);
/**
* Render Home
*
* @returns ReactElement<any>
*/
render(): ReactElement<any> {
this.test.a();
this.test.b();
return (
<div>
<Head>
<title>home</title>
</Head>
<main>
<p>test</p>
</main>
</div>
);
}
}
控制台输出
hi from test
a
b
发生这种情况的任何原因?
解决方法
经过一个小时的睡眠和大量的咖啡研究后......我找到了解决方案!
我试图操作 getter 而不是设置属性值。 这导致了以下代码:
/**
* Inject dependency through property
*
* @param targetClass
* @returns PropertyDecorator
*/
export const inject = (targetClass: InjectionToken): PropertyDecorator => {
if (!targetClass || targetClass === undefined) {
throw new Error(`${targetClass} class is undefined`);
}
return (target: any,propertyKey: string | symbol): PropertyDescriptor | undefined => {
if (!Reflect.deleteProperty(target,propertyKey)) {
throw new Error(`Could not delete property ${String(propertyKey)} in class ${target.constructor.name}`);
}
const options: PropertyDescriptor = {
value: container.resolve(targetClass)
};
if (!Reflect.defineProperty(target,propertyKey,options)) {
throw new Error(`Could not define ${String(propertyKey)} property in class ${targetClass.toString()}`);
}
return Reflect.getOwnPropertyDescriptor(target,propertyKey);
};
};
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。