Repository: angular
Issue: [FR] Introduce component-scope and custom scopes in DI
Labels: feature,area: core,core: di,feature: under consideration

### Which @angular/* package(s) are relevant/related to the feature request?

core

### Description

Currently, all services that are declared on the module-level are singletons. It is not possible to my knowledge to have a different lifecycle, for example to have multiple stateful service-instances, each associated with a component.

When declaring a service-provider on the component-level, this is possible with `@Host()`, but then it is impossible for downstream-projects to override the service-implementation-class in their modules. The provider declared in `@Component(...)` wins over any provider-declaration in any module.

The lifecycle should be independent from the type-declaration! It should be possible to somehow (e.g. using `@Host()`) declare a local instance of the service, but still use the type declared in the module's provider.

Besides this concrete use-case, Angular should support custom scopes, just like Java's CDI does. With the current service-architecture in Angular (i.e. every service being either a singleton or not being overridable by downstream-projects), it is most often impossible to implement a stateful service.

I also tried using a custom factory and access the `Injector`, but I saw in the debugger, that my factory is not consulted, if there is already a service-instance existing. I therefore cannot put the lookup-logic (of whether to reuse an existing instance or create a new instance for my current situation) into my own factory.

In Java's CDI, a current thread running can enter (and exit) custom scopes manually and access the proper injected service-instance having declared an active scope.

### Proposed solution

1. Make `@Host()` work with services declared on the module-level. If a component declares `@Host()` it should get its own *instance* of the service, but the class-declaration should be taken from the module and thus still be overridable by a downstream-module. The child-components should automatically (or if needed with an additional `SkipSelf()`) use the service-instance of their parent-container (recursively). This would solve our immediate problem of not being able to associate a stateful service-instance with a component in a 1-1-relation.
2. Introduce custom scopes just like Java's CDI does.
3. A provider could -- additionally to the `useFactory` -- be declared with a newly introduced `useRegistry`. In contrast to the factory, the registry is consulted directly and it is up to the registry whether it wants to return an existing instance or create a new one. The registry-implementation needs access to the current injection-situation, of course. I'm not sure, but this may be possible via getting the current `Injector` as one of the `deps`. Since my factory wasn't consulted, if the instance already existed, I didn't analyse this further.
4. Just in case, this is not yet possible: The injection-point should be accessible to the registry, just like in CDI (see `javax.enterprise.inject.spi.InjectionPoint`).

### Alternatives considered

I didn't find any alternative, but maybe I overlooked something. Please let me know, if I did!

As alternative, we could (and currently do) use stateless services, because the service-instances are singletons. With this approach they can be overridden (replaced by another implementation) downstream (the app might need another implementation than provided by default by the lib).

Stateless services suck for what we want to achieve. It's like writing a procedural language (e.g. C) -- but we like OO for a reason :smirk:

Declaring the service in `@Component` is not possible, because we then cannot override the service-implementation downstream. This is essential to us!