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

Use @registry to inject only into one class? #125

Open
gmenih opened this issue Oct 6, 2020 · 5 comments
Open

Use @registry to inject only into one class? #125

gmenih opened this issue Oct 6, 2020 · 5 comments
Assignees

Comments

@gmenih
Copy link

gmenih commented Oct 6, 2020

I'm trying to use @registry to inject a Logger into providers, but I want the logger to have some context of where it's being injected to.

So I created this simple decorator, which will take the target.name, so that Logger knows where it was registered, and can then add a prefix to every log message of the parent class name.

export function registerLogger(): ClassDecorator {
    return (target) =>
        registry([
            {
                token: Logster,
                useFactory: () => {
                    return new Logger(target.name);
                },
            },
        ])(target);
}

// ... 
// usage
@injectable()
@registerLogger()
export class SomeService {
    // ...
}

This would inject a Logger which would prefix every log message with [SomeService] . But, I realised that @registry will always overwrite the token, so wherever I call @registerLogger last, it will use that class for every instance of the logger.

Am I tackling this completely wrong? Is it possible to do this the way I imagined, or should I take some other path?

@Xapphire13
Copy link
Collaborator

Xapphire13 commented Oct 8, 2020

Hi @gmenih341, so this is because of how registrations work in TSyringe, they are attached to the token, not to the class you use registry() on. In order for this to work, you would need to use a token unique to the decorated class, or we would need to extend the factory function to be passed in the resolution target (so you could do target.name in the factory).

This functionality has been asked for and work started on it here #56, but that PR went stale some time ago (the author never came back to update it).

Would this be something you'd be interested in working on?

@gmenih
Copy link
Author

gmenih commented Oct 9, 2020

@Xapphire13 ah, got it! So an alternative solution for this would be to generate a unique token each time and then use @inject for every use of Logger, or to create a child container and then use child.register to specify which container a token is provided in?

Yeah, looking at #56, it seems like that it wouldn't be hard to achieve what is still missing in that PR. I could definitely take it - should I continue on that branch, or start from scratch?

@Xapphire13
Copy link
Collaborator

Let me ping in that PR to see if we can get any traction there first. If not, maybe fork it into a new branch.

@Xapphire13
Copy link
Collaborator

Since there was no response in the original PR, I'm not entirely sure what the etiquette is haha. I would suggest forking that PR and submitting a new one

@gmenih
Copy link
Author

gmenih commented Oct 15, 2020

All right, I'll check it out and try to submit a PR sometime this weekend :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants