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:
@@ -1,10 +1,10 @@
|
||||
import { inject, type InjectionKey } from 'vue';
|
||||
import type { useCollectionState } from '@/presentation/components/Shared/Hooks/UseCollectionState';
|
||||
import type { useApplication } from '@/presentation/components/Shared/Hooks/UseApplication';
|
||||
import type { useRuntimeEnvironment } from '@/presentation/components/Shared/Hooks/UseRuntimeEnvironment';
|
||||
import type { useClipboard } from '@/presentation/components/Shared/Hooks/Clipboard/UseClipboard';
|
||||
import type { useCurrentCode } from '@/presentation/components/Shared/Hooks/UseCurrentCode';
|
||||
import type { useAutoUnsubscribedEvents } from '@/presentation/components/Shared/Hooks/UseAutoUnsubscribedEvents';
|
||||
import type { InjectionKey } from 'vue';
|
||||
|
||||
export const InjectionKeys = {
|
||||
useCollectionState: defineTransientKey<ReturnType<typeof useCollectionState>>('useCollectionState'),
|
||||
@@ -15,10 +15,68 @@ export const InjectionKeys = {
|
||||
useCurrentCode: defineTransientKey<ReturnType<typeof useCurrentCode>>('useCurrentCode'),
|
||||
};
|
||||
|
||||
function defineSingletonKey<T>(key: string): InjectionKey<T> {
|
||||
return Symbol(key) as InjectionKey<T>;
|
||||
export interface InjectionKeyWithLifetime<T> {
|
||||
readonly lifetime: InjectionKeyLifetime;
|
||||
readonly key: InjectionKey<T> & symbol;
|
||||
}
|
||||
|
||||
function defineTransientKey<T>(key: string): InjectionKey<() => T> {
|
||||
return Symbol(key) as InjectionKey<() => T>;
|
||||
export interface SingletonKey<T> extends InjectionKeyWithLifetime<T> {
|
||||
readonly lifetime: InjectionKeyLifetime.Singleton;
|
||||
readonly key: InjectionKey<T> & symbol;
|
||||
}
|
||||
|
||||
export interface TransientKey<T> extends InjectionKeyWithLifetime<() => T> {
|
||||
readonly lifetime: InjectionKeyLifetime.Transient;
|
||||
readonly key: InjectionKey<() => T> & symbol;
|
||||
}
|
||||
|
||||
export type AnyLifetimeInjectionKey<T> = InjectionKeyWithLifetime<T> | TransientKey<T>;
|
||||
|
||||
export type InjectionKeySelector<T> = (keys: typeof InjectionKeys) => AnyLifetimeInjectionKey<T>;
|
||||
|
||||
export function injectKey<T>(
|
||||
keySelector: InjectionKeySelector<T>,
|
||||
vueInjector = inject,
|
||||
): T {
|
||||
const key = keySelector(InjectionKeys);
|
||||
const injectedValue = injectRequired(key.key, vueInjector);
|
||||
if (key.lifetime === InjectionKeyLifetime.Transient) {
|
||||
const factory = injectedValue as () => T;
|
||||
const value = factory();
|
||||
return value;
|
||||
}
|
||||
|
||||
return injectedValue as T;
|
||||
}
|
||||
|
||||
export enum InjectionKeyLifetime {
|
||||
Singleton,
|
||||
Transient,
|
||||
}
|
||||
|
||||
function defineSingletonKey<T>(key: string): SingletonKey<T> {
|
||||
return {
|
||||
lifetime: InjectionKeyLifetime.Singleton,
|
||||
key: Symbol(key),
|
||||
};
|
||||
}
|
||||
|
||||
function defineTransientKey<T>(key: string): TransientKey<T> {
|
||||
return {
|
||||
lifetime: InjectionKeyLifetime.Transient,
|
||||
key: Symbol(key),
|
||||
};
|
||||
}
|
||||
|
||||
function injectRequired<T>(
|
||||
key: InjectionKey<T>,
|
||||
vueInjector = inject,
|
||||
): T {
|
||||
const injectedValue = vueInjector(key);
|
||||
|
||||
if (injectedValue === undefined) {
|
||||
throw new Error(`Failed to inject value for key: ${key.description}`);
|
||||
}
|
||||
|
||||
return injectedValue;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user