首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >tsyringe container.resolve在自定义装饰器中创建一个新的调用实例

tsyringe container.resolve在自定义装饰器中创建一个新的调用实例
EN

Stack Overflow用户
提问于 2020-12-22 02:22:52
回答 1查看 685关注 0票数 2

我正试图为tsyringe创建一个自定义装饰器,以便通过属性注入。

我的代码:

代码语言:javascript
运行
复制
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))
        });
    };
};

服务

代码语言:javascript
运行
复制
import { injectable } from 'tsyringe';

@injectable()
export class Test {
    constructor() {
        console.log('hi from test');
    }

    a(): void {
        console.log('a');
    }

    b(): void {
        console.log('b');
    }
}

呼叫类

代码语言:javascript
运行
复制
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>
    );
  }
}

控制台输出

代码语言:javascript
运行
复制
hi from test
a
hi from test
b

当前行为:每次调用注入类的方法时,都会再次调用构造函数。因此,这意味着我的类在每次新调用时都会得到新的初始化。

当我使用下面的代码时,一切似乎都正常。

代码语言:javascript
运行
复制
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>
    );
  }
}

控制台输出

代码语言:javascript
运行
复制
hi from test
a
b

为什么会发生这种事?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-12-22 07:17:28

睡了一个小时,喝了很多咖啡,做了些研究.我找到解决办法了!

我试图操纵getter而不是设置属性值。这导致了以下代码:

代码语言:javascript
运行
复制
/**
 * 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);
    };
};
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65402497

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档