X Tutup
The Wayback Machine - https://web.archive.org/web/20200628004218/https://github.com/angular/angular/issues/35497
Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: Specify behaviour of providers for generic types #35497

Open
Alphish opened this issue Feb 17, 2020 · 0 comments
Open

docs: Specify behaviour of providers for generic types #35497

Alphish opened this issue Feb 17, 2020 · 0 comments

Comments

@Alphish
Copy link

@Alphish Alphish commented Feb 17, 2020

📚 Docs or angular.io bug report

Description

Right now, the documentation doesn't specify what happens when services are injected using type tokens with generic parameters (such as MyGenericService<number> or MyGenericService<string>), or at least I haven't found such a place.

The behaviour can be tested - currently different variations of generic service have the same underlying instance (unless overriden in injection hierarchy). However, without it being documented I can't be certain it's an intended/accepted behaviour, and thus can't safely rely on it.

An example use-case where I'd like to rely on this behaviour:

  • have a generic service MyGenericService<TData>, where TData would be used for stronger type-checking of type-specific properties/methods
  • provide the service somewhere in DI hierarchy
  • inject an instance of service as MyGenericService<ConcreteData> in a component/directive/service that passes/receives ConcreteData instances to/from the service
  • inject the same instance of service as MyGenericService<any> to other component/directive/service that doesn't rely on type-specific properties/methods of the service

🔬 Minimal Reproduction

What's the affected URL?**

https://angular.io/guide/dependency-injection-providers#the-provider-object-literal

Reproduction Steps**

Given a setup like this and an instance of TestComponent somewhere:

class TestGenericService<TGeneric> {
  randomId: number;
  constructor() {
    console.log('Creating test generic service');
    this.randomId = Math.random();
  }
}

@Component({
  selector: 'test-component',
  template: '',
  providers: [
    // the generic type in "provide" is not allowed
    // { provide: TestGenericService<number>, useClass: TestGenericService<number> },
    { provide: TestGenericService, useClass: TestGenericService }
  ]
})
export class TestComponent {
  constructor(
    public numberTest: TestGenericService<number>,
    public stringTest: TestGenericService<string>
) {
    console.log('ID for number test');
    console.log(this.numberTest.randomId);
    console.log('ID for string test');
    console.log(this.stringTest.randomId);
  }
}

I get the following console output:

Creating test generic service
ID for number test
0.9302127796181012
ID for string test
0.9302127796181012

From my tests I've found that:

  • I cannot create a provider for type-with-generic-arguments injection token, even if I wanted to; the type injection token must always be given in its non-generic form
  • I cannot pass a constructor parameter with generic type without its type arguments passed (the exact opposite of what happens in provider definition, and also common sense)
  • based on console output, the provided service (TestGenericService) was created only once and both resolved constructor arguments (TestGenericService, TestGenericService) are in fact the same instance of TestGenericService

It's a reasonable behaviour, especially since there's no way to define an injection token with generic type argument in the first place. However, tests are needed to confirm this behaviour. Also, there's no guarantee this behaviour won't change, especially if sometime in the future Angular would be able to obtain generic type information (which now is unavailable, according to this SO answer).

Expected vs Actual Behavior**

I'd like to have the behaviour of generic type providers specified in the documentation. "The Provider object literal" section of Dependency Injection >> DI Providers page seems like a good place to specify that.

Additional tests might be needed to ensure the current behaviour doesn't break, if none are present at the moment.

🌍 Your Environment

Browser info

Google Chrome 79

@ngbot ngbot bot added this to the needsTriage milestone Feb 18, 2020
@ngbot ngbot bot modified the milestones: needsTriage, Backlog Feb 24, 2020
@aikidave aikidave added this to Pending - Top of backlog in docs Feb 24, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
docs
Pending - Top of backlog
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants
You can’t perform that action at this time.
X Tutup