I tried to come up with the simplest possible, useful, async DI container I could think of, and here's the result:
function Container(provider) {
const cache = {};
const container = function (name) {
if (!cache[name]) {
cache[name] = provider[name](container);
}
return cache[name];
}
return container;
}
Totally trivial - you provide an object (provider
) where each property is a function that receives the container and returns a Promise that resolves to a service.
Here's a simple use-case:
class UserCache { }
class UserService {
constructor(private cache: UserCache) { }
}
And usage:
const container = Container({
"cache": async c => new UserCache(),
"user-service": async c => new UserService(await c("cache"))
});
// and a simple test:
container("user-service").then(service => {
console.log(service);
container("user-service").then(same_service => {
console.log(service === same_service); // true
});
});
You can try it here.
This is actually surprisingly powerful - for example, you can bootstrap multiple service-providers like this:
const container = Container({
...UserServices,
...WebServices,
});
What I can't figure out, is how to make it type-safe - I know I'll need generics and keyof
, but I could really use some help in this area.
Any takers? :-)