Skip to content

fix(di): allow injecting event emitter fns without specifying type annotation#1155

Closed
pkozlowski-opensource wants to merge 1 commit into
angular:masterfrom
pkozlowski-opensource:issue965
Closed

fix(di): allow injecting event emitter fns without specifying type annotation#1155
pkozlowski-opensource wants to merge 1 commit into
angular:masterfrom
pkozlowski-opensource:issue965

Conversation

@pkozlowski-opensource
Copy link
Copy Markdown
Member

Fixes #965

@vsavkin I'm not sure this is the best possible fix but I guess you are the most familiar with this part of the code, so would be great if you could review this one.

The basic problem was that without a type annotation binding couldn't figure out a token for DependencyAnnotations while it seems that ElementInjector doesn't care that much about the token itself but is more interested in dependency properties. In this respect any token would do.

@pkozlowski-opensource
Copy link
Copy Markdown
Member Author

Adding to M7 as the issue it is fixing is in M7

@pkozlowski-opensource pkozlowski-opensource added this to the M7: GT Customer milestone Mar 31, 2015
Comment thread modules/angular2/src/di/binding.js Outdated
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does not really look right to me.

It only works because the token value is not taken into account in the @EventEmitter case - it works as long as the token has a value.

May be a better way to solve this would be to add an implicitType property to DependencyAnntotaion (or a derived class) that would be initialized to Function for EventEmitter ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, I was also uneasy about this approach. @vicb what would be the interaction between implicitType and token? Maybe @EventEmitter & co. should simply have token property?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking about token = ann.implicitType but actually you're right ann.implicitToken would probably be better as it could be anything (w/ or w/o the "implicit" prefix)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. So the only problem I can see that with this we are going to have 2 different "sources" of tokens - either a type annotation or a token from the @EventEmitter and we will need to somehow deal with a situation where both parties differ in an opinion on what a token should be...

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As of today the implicitToken would only be used to give token whatever value for the else branch no to be taken - we actually don't care about the actual value.

Maybe we could have a special annotation class DependencyAnnotationNoToken extends DependencyAnnotation that would avoid the branch, ie else if (!noToken) (noToken would be set to true if any annotation is instanceof DependencyAnnotationNoToken) ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can inject EventEmitter without specifying the type annotation as follows:

@Inject(Function) @EventEmitter('onChange') eventEmitter

But it is not very clean.

I think that what we should do.

We can change the DependencyAnnotation type to look like this:

class DependencyAnnotation {
  //...
  get token(){return null}
  //...
}

So DependencyAnnotation must have the token getter. And if it returns a non-blank token, we use it.

Moreover, we can potentially make Inject, InjectLazy, and InjectAsync extend DependencyAnnotation. Currently, all of them have this interface:

interface Inject{
  get token()
}

So it will work.

Finally, what happens if you have more than one annotation providing the token applied to the same parameter? Currently, the last one wins. So we can keep this behavior.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vsavkin perfect, understood. Will update the PR accordingly.

@pkozlowski-opensource
Copy link
Copy Markdown
Member Author

@vicb @vsavkin I've changed the DependencyAnnotation as suggested by @vsavkin
Could you please have another look?

@pkozlowski-opensource
Copy link
Copy Markdown
Member Author

The only part I wasn't comfortable with was

Moreover, we can potentially make Inject, InjectLazy, and InjectAsync extend DependencyAnnotation

The way I read current code / docs is that DependencyAnnotation has "special meaning" to the framework and as such I don't think "core" DI annotations should extend it. What we could do, though, is to create a new annotation (TokenAware ?) and have it extended by both DependencyAnnotation and other DI annotations that are providing a token. WDYT? I could handle this in a separate PR.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add some inline comments

@vicb
Copy link
Copy Markdown
Contributor

vicb commented Apr 2, 2015

lgtm, I don't see the need to make Inject, InjectLazy, and InjectAsync extend DependencyAnnotation.

@angular-automatic-lock-bot
Copy link
Copy Markdown

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot Bot locked and limited conversation to collaborators Sep 6, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

@EventEmitter Requires Type

6 participants