Refactor DI for simplicity and type safety
This commit improves the dependency injection mechanism by introducing a custom `injectKey` function. Key improvements are: - Enforced type consistency during dependency registration and instantiation. - Simplified injection process, abstracting away the complexity with a uniform API, regardless of the dependency's lifetime. - Eliminated the possibility of `undefined` returns during dependency injection, promoting fail-fast behavior. - Removed the necessity for type casting to `symbol` for injection keys in unit tests by using existing types. - Consalidated imports, combining keys and injection functions in one `import` statement.
This commit is contained in:
53
tests/integration/composite/DependencyResolution.spec.ts
Normal file
53
tests/integration/composite/DependencyResolution.spec.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { it, describe, expect } from 'vitest';
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
import { defineComponent, inject } from 'vue';
|
||||
import { InjectionKeySelector, InjectionKeys, injectKey } from '@/presentation/injectionSymbols';
|
||||
import { provideDependencies } from '@/presentation/bootstrapping/DependencyProvider';
|
||||
import { buildContext } from '@/application/Context/ApplicationContextFactory';
|
||||
import { IApplicationContext } from '@/application/Context/IApplicationContext';
|
||||
|
||||
describe('DependencyResolution', () => {
|
||||
describe('all dependencies can be injected', async () => {
|
||||
// arrange
|
||||
const context = await buildContext();
|
||||
const dependencies = collectProvidedKeys(context);
|
||||
Object.values(InjectionKeys).forEach((key) => {
|
||||
it(`"${key.key.description}"`, () => {
|
||||
// act
|
||||
const resolvedDependency = resolve(() => key, dependencies);
|
||||
// assert
|
||||
expect(resolvedDependency).to.toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
type ProvidedKeys = Record<symbol, unknown>;
|
||||
|
||||
function collectProvidedKeys(context: IApplicationContext): ProvidedKeys {
|
||||
const providedKeys: ProvidedKeys = {};
|
||||
provideDependencies(context, {
|
||||
inject,
|
||||
provide: (key, value) => {
|
||||
providedKeys[key as symbol] = value;
|
||||
},
|
||||
});
|
||||
return providedKeys;
|
||||
}
|
||||
|
||||
function resolve<T>(
|
||||
selector: InjectionKeySelector<T>,
|
||||
providedKeys: ProvidedKeys,
|
||||
): T | undefined {
|
||||
let injectedDependency: T | undefined;
|
||||
shallowMount(defineComponent({
|
||||
setup() {
|
||||
injectedDependency = injectKey(selector);
|
||||
},
|
||||
}), {
|
||||
global: {
|
||||
provide: providedKeys,
|
||||
},
|
||||
});
|
||||
return injectedDependency;
|
||||
}
|
||||
3
tests/integration/composite/README.md
Normal file
3
tests/integration/composite/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Composite Tests
|
||||
|
||||
The `composite` directory contains integration tests that validate the cooperative functionality of multiple components within the application, going beyond unit tests to ensure interconnected parts perform as expected.
|
||||
Reference in New Issue
Block a user