Created
June 26, 2023 05:32
-
-
Save justmoon/762361291fc1b43c7bd012b765de4f42 to your computer and use it in GitHub Desktop.
Another idea for dependency injection with runtime access to the dependency tree
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const makeComponent = <TDeps extends Dependencies, TProduct>(dependencies: TDeps, factory: (deps: ResolvedDependencies<TDeps>) => TProduct): SmartFactory<TProduct, TDeps> => { | |
const smartFactory = (predefinedDependencies = new Map()) => { | |
const resolvedDependencies: Partial<ResolvedDependencies<TDeps>> = {} | |
for (const key of Object.keys(dependencies)) { | |
if (predefinedDependencies.has(dependencies[key])) { | |
resolvedDependencies[key as keyof ResolvedDependencies<TDeps>] = predefinedDependencies.get(dependencies[key]) as ResolvedDependencies<TDeps>[string] | |
} else { | |
const resolvedDependency = dependencies[key](predefinedDependencies) as ResolvedDependencies<TDeps>[string] | |
resolvedDependencies[key as keyof ResolvedDependencies<TDeps>] = resolvedDependency | |
predefinedDependencies.set(dependencies[key], resolvedDependency) | |
} | |
} | |
return factory(resolvedDependencies as ResolvedDependencies<TDeps>) | |
} | |
smartFactory.dependencies = dependencies | |
return smartFactory | |
} | |
const Bar = makeComponent({}, () => { | |
return "This is Bar!" | |
}) | |
const Foo = makeComponent({ | |
bar: Bar | |
}, (dependencies) => { | |
console.log(dependencies.bar) | |
}) | |
type ResolvedDependencies<TDeps extends Dependencies> = { | |
[K in keyof TDeps]: ReturnType<TDeps[K]> | |
} | |
type Dependencies = Record<string, SmartFactory<unknown, any>> | |
type Factory = (dependencies: Dependencies) => unknown | |
type SmartFactory<TProduct, TDeps extends Dependencies> = { | |
(predefinedDependencies?: Map<SmartFactory<unknown, any>, unknown>): TProduct | |
dependencies: TDeps | |
} | |
Foo() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment