Repository: angular
Issue: Feat: transient(...) function to complement the inject(...) function
Labels: feature,area: core,core: di

### Which @angular/* package(s) are relevant/related to the feature request?

_No response_

### Description

With standalone components comes great responsibility - especially regarding service lifetimes. 

The problem is that components will need some services, and it's a lot of guessing which ones have already been added to `providers` at a level above, which services should start anew (because they have state, which shouldn't be modified by sub-components by accident) and much more. 

My experience is that this leads to over-use `providers: [...]` because it's often a guesswork which providers are available from parent-level components and which ones are net. having everything it the own `providers[...]` has a smell 💩 to it though. 

Basically sub-components could forget their own providers - and everything works - but this will result in them sharing the service by accident. 

So it's fine if it's on purpose, but my experience is that it's accidental a lot, leading to difficult to debug issues. 

### Proposed solution

I propose a `transient(...)` method which is similar to `inject(...)`, except that it ensures that the service it creates is only created once, and never reused. 

This would kind of result in shorter, nicer code 

```typescript
@Component({
  // selector etc.
})
export class Example {
  private = transient(ViewService);
}
```

...than before (where you could never ensure that sub-components would reuse your service): 

```typescript
@Component({
  // selector etc.
  providers: [
    ViewService,
  ],
})
export class Example {
  private = inject(ViewService);
}
```

The code for the `transient(...)` which works looks like this - but I'm sure there's room for improvement:

```typescript
import { Injector, ProviderToken, TypeProvider, inject } from '@angular/core';

/**
 * Transient dependency injection provider.
 * This will create a new instance of the provided token,
 * without making it available in sub-components
 * as would happen with providers in a component.
 * 
 * @param token the class which is injectable
 * @param injector the injector to use, if not provided, the current injector will be used.
 *     Not not necessary when using transient in the class properties construction or in the constructor,
 *     as the injector will be available in the constructor.
 *     But necessary when using transient inside anything else.
 * @returns 
 */
export function transient<T>(token: ProviderToken<T>, injector?: Injector): T {
  // make sure we have an injector
  // this will throw an error, if transient is used outside of construction and without providing an injector
  injector ??= inject(Injector);

  // create a new injector which is only meant to be used for this transient instance
  const subInjector = Injector.create({
    providers: [
      token as TypeProvider
    ],
    parent: injector
  });

  // return the instance
  return subInjector.get(token, undefined, { self: true });
}
```

### Alternatives considered

I guess we could also 

1. extend the inject-options to provide flags for this as well, but I think this would be simpler and clearer. 
2. Change the signature of services so they could be marked as `transient` and therefor the injector would always create a new service - this would be a welcome addition anyhow, but my recommendation with the `transient(...)` injector would still be great, because you would not have to define the `providers` just to get a service.