Skip to content

Commit

Permalink
增加测试用例-验证循环依赖的状态
Browse files Browse the repository at this point in the history
  • Loading branch information
kaokei committed Nov 22, 2024
1 parent 048beba commit 65b6d60
Show file tree
Hide file tree
Showing 10 changed files with 127 additions and 4 deletions.
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export const CURRENT_COMPONENT = createToken<ComponentInternalInstance>(
interface ContainerOptions extends interfaces.ContainerOptions {
instance?: ComponentInternalInstance | null;
}
export type ExtractToken<T> = T extends interfaces.Newable<infer U> ? U : never;
export type ExtractToken<T> = T extends interfaces.Newable<infer U> ? U : T;

const DEFAULT_CONTAINER_OPTIONS: ContainerOptions = {
autoBindInjectable: false,
Expand Down
3 changes: 1 addition & 2 deletions tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,5 +69,4 @@
10. 异常场景
1. 验证useService在组件外调用场景
2. 多次调用postReactive
3. 循环依赖
4. 验证token是否可以解决循环依赖
3. 循环依赖-验证token是否可以解决循环依赖-经验证是解决不了的
2 changes: 1 addition & 1 deletion tests/test17/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
## 测试场景

useService 在 app.runWithContext 中执行
卸载组件或者卸载app时,会调用unbindAll方法
24 changes: 24 additions & 0 deletions tests/test17/demo.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,36 @@ import { mount } from '@vue/test-utils';
import DemoComp from './DemoComp.vue';
import { DemoService } from './DemoService';
import { OtherService } from './OtherService';
import { App } from 'vue';
import { declareAppProviders } from '../../src';

describe('test17', () => {
it('get DemoService instance', async () => {
const wrapper = mount(DemoComp);

expect(wrapper.vm.demoService).toBeInstanceOf(DemoService);
expect(wrapper.vm.otherService).toBeInstanceOf(OtherService);

wrapper.unmount();
});

it('get DemoService instance', async () => {
let rootApp!: App;

const wrapper = mount(DemoComp, {
global: {
plugins: [
(app: App) => {
rootApp = app;
},
declareAppProviders([DemoService, OtherService]),
],
},
});

expect(wrapper.vm.demoService).toBeInstanceOf(DemoService);
expect(wrapper.vm.otherService).toBeInstanceOf(OtherService);

rootApp.unmount();
});
});
41 changes: 41 additions & 0 deletions tests/test18/DemoComp.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<script setup lang="ts">
import { declareProviders, useService } from '../../src/index';
import { DemoService } from './DemoService';
import { OtherService } from './OtherService';
import { TYPES } from './token';
declareProviders(con => {
con.bind(TYPES.DemoService).to(DemoService);
con.bind(TYPES.OtherService).to(OtherService);
});
const demoService = useService(TYPES.DemoService);
const otherService = useService(TYPES.OtherService);
defineExpose({
demoService,
otherService,
});
</script>

<template>
<div>
<div class="demo-count">{{ demoService.count }}</div>
<div class="other-count">{{ otherService.count }}</div>

<button
type="button"
class="btn-count-demo"
@click="demoService.increaseCount()"
>
Add count demo
</button>

<button
type="button"
class="btn-count-other"
@click="otherService.increaseCount()"
>
Add count other
</button>
</div>
</template>
14 changes: 14 additions & 0 deletions tests/test18/DemoService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { inject, LazyServiceIdentifier } from 'inversify';
import { TYPES } from './token';
import { ExtractToken } from '../../src';

export class DemoService {
public count = 1;

public increaseCount() {
this.count++;
}

@inject(new LazyServiceIdentifier(() => TYPES.OtherService))
public otherService!: ExtractToken<typeof TYPES.OtherService>;
}
14 changes: 14 additions & 0 deletions tests/test18/OtherService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { inject, LazyServiceIdentifier } from 'inversify';
import { TYPES } from './token';
import { ExtractToken } from '../../src';

export class OtherService {
public count = 1;

public increaseCount() {
this.count++;
}

@inject(new LazyServiceIdentifier(() => TYPES.DemoService))
public demoService!: ExtractToken<typeof TYPES.DemoService>;
}
10 changes: 10 additions & 0 deletions tests/test18/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
## 测试场景

验证循环依赖,LazyServiceIdentifier 也不能解决循环依赖的问题

这是一个大问题,我以为属性注入器可以避免循环依赖已经是行业共识了,比如Spring中就是这么处理的。

但是inversify居然不是这么处理的,显然是收集完所有属性之后才会放入缓存系统。

比较简单的方案就是采用二级缓存,假设现在的缓存cache是最终的缓存结果。
那么再增加一层tempCache,这个缓存只是临时存储实例化对象,方便被其他对象依赖时可以从缓存中获取该对象。
13 changes: 13 additions & 0 deletions tests/test18/demo.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import 'reflect-metadata';
import { mount } from '@vue/test-utils';
import DemoComp from './DemoComp.vue';

describe('test18', () => {
it('get DemoService instance', async () => {
expect(() => {
mount(DemoComp);
}).toThrow(
'Circular dependency found: Symbol(DemoService) --> Symbol(OtherService) --> Symbol(DemoService)'
);
});
});
8 changes: 8 additions & 0 deletions tests/test18/token.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { DemoService } from './DemoService';
import { OtherService } from './OtherService';
import { createToken } from '../../src/index';

export const TYPES = {
DemoService: createToken<DemoService>('DemoService'),
OtherService: createToken<OtherService>('OtherService'),
};

0 comments on commit 65b6d60

Please sign in to comment.