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

Accept token factories as arguments to injected #23

Open
smithki opened this issue Jul 17, 2022 · 2 comments
Open

Accept token factories as arguments to injected #23

smithki opened this issue Jul 17, 2022 · 2 comments
Labels
enhancement New feature or request

Comments

@smithki
Copy link

smithki commented Jul 17, 2022

I'm interested in using a pattern like this for injected services:

import { injected, token } from 'brandi';

class MyService {
  static token = token<MyService>('MyService');

  // ...
}

injected(MyService, /* ... */);

so that token mappings are co-located with their relevant service implementations. But, there could be an issue if I introduce circular dependencies... for example:

// ./name.service.ts
import { injected, token } from 'brandi';
import { Logger } from './logger.service';

class NameService {
  static token = token<NameService>('NameService');

  constructor(private readonly log: Logger) {}

  async getName() {
    this.log.debug('called NameService.getName()');
    return 'Sally';
  }
}

injected(NameService, Logger.token);

// ./logger.service.ts
import { injected, token } from 'brandi';
import { NameService } from './name.service';

class Logger {
  static token = token<Logger>('Logger');

  constructor(private readonly nameSvc: NameService) {}

  async sayHello() {
    const name = await this.nameSvc.getName();
    console.log(`Hello, my name is ${name}!`);
  }

  debug(message: string) {
    console.log('[debug]', message);
  }
}

injected(Logger, NameService.token);

I think this could be resolved by allowing tokens to be provided as functions, like:

injected(MyService, () => MyOtherService.token, ...);

Then the token could be fully resolved when container.get() is called.

@vovaspace
Copy link
Owner

Hi!

It’s clear what the problem is but it seems that the problem can be solved in a different way. You can move the token to a separate file like tokens.ts or MyService.token.ts.

Brandi is also design to be used on the frontend, and the way you suggested provokes extra code entering the bundle when you import MyService for the token, but do not actually use the class implementation.

@vovaspace vovaspace added the enhancement New feature or request label Jul 25, 2022
@vovaspace
Copy link
Owner

vovaspace commented Jul 25, 2022

Oh wait… I didn't see that you want to use circular dependencies.

Thus it is more complex problem. Moving tokens doesn’t resolve that. And I guess your way won't resolve that too.

Something like Inversify's lazy identifiers is needed here. But it would be better to just avoid circular dependencies.

@vovaspace vovaspace reopened this Jul 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants