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 }); });
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? :-)
Top comments (2)
It's checking the keys - so far so good:
Now to figure out the generic return-type...
Someone has been helpful on StackOverflow already - it's partially type-hinted now!
stackoverflow.com/questions/511764...