feat: lazy injection
Merge branch 'lazy-inject'
feat: transient scope

When a provider is annotated with `TransientScope`, a new instance is
created every time somebody asks for it.

In general, scopes can be used in order to force
new instance (eg. `RouteScope` might force new instance of `Cache`,
per application route, which means a new instance of `Cache` is created
every time a route changes).

`TransientScope` is basically a built-in scope that always forces a new
instance.