I have long thought about the DI container and IoC stuff. I wrote several pretty big apps with Google Closure Library.
I always tried to avoid big bull of mud code, but it wasn't easy. I tried to make everything pluggable, replaceable, so that's how
github.com/steida/este-library was born.
Library is somehow clean now, but app code still sucks. The golden rule I learned was: Do not use global object, inject everything, service locator is evil, dependency injection ftw.
With such approach my apps become much more cleaner etc., but I had to write a lot of boring boilerplate wiring code. Factories, plugin configuration etc.
I was doing "bastard injection" and "poor man's injection', and despite pattern naming, it was a huge win for code quality.
When designing, I tried to avoid several common mistakes of DI container design or usage.
1) This container can't be used as service locator. There is a detection and nice warning message.
2) This container does auto-registration, so you don't have to register anything. Just create class and consume it where need. Done.
3) This container is not "stringly typed". It parses type annotations and use parsed typed for container generation.
4) This container is developed with strict TDD in mind.
5) This container does not breaks advanced compilation and does not add any overhead.
6) There is no run time magic, generated code can be easily viewed and debugged, if needed.
Of course there are still lot of work to be done, for example: decorators, as and by resolvers, full type expression parsing (huge possibilities), managing lifestyle and more.
But I pushed it to npm anyway, because I am using it already in real project, so I consider it as ready for production.
Question?