Skip to content

poc: [For Evaluation] example implementation of assisted injection - #127

Open
kalymero wants to merge 2 commits into
gbtb16:masterfrom
kalymero:feat/assisted_injection
Open

poc: [For Evaluation] example implementation of assisted injection#127
kalymero wants to merge 2 commits into
gbtb16:masterfrom
kalymero:feat/assisted_injection

Conversation

@kalymero

@kalymero kalymero commented Mar 9, 2025

Copy link
Copy Markdown

Hi Gabriel,
Kiwi is a very simple and beautiful DI framework, congrats!

I think a missing key feature is assisted injection, so here i've put together an example implementation for you to evaluate.
Another option would be using Records instead of Maps for the arguments, but it will require the bump of the SDK version to at least > 3.0.0

Let me know how you feel about it and if it makes sense for you.

@juarezfranco

Copy link
Copy Markdown

Hello, in my opnion, this approach creates a tight coupling between the IoC container and object creation. Instead of injecting a function with dynamic parameters, why not register a factory in the container? That way, the container resolves the factory, and the factory handles object creation with the required parameters. This keeps the DI setup cleaner and avoids unnecessary complexity.

for example

final factory = container.resolve<MyServiceFactory>();
final service = factory.create("123", 5)

or you can register a builder

final builder = container.resolve<MyServiceBuilder>();
final myService = builder
    .setId("123")
    .setCount(5)
    .build();

@kalymero

kalymero commented Mar 17, 2025

Copy link
Copy Markdown
Author

Hi @juarezfranco, thanks.
Yes, the factory approach is what i'm currently using but i thought that having a built-in assisted injection mechanism would be nice.
At the end of the day, you can see it as a factory method implemented by the container itself.

Dart limitations don't help here, but it would be nice to pass a list of typed parameters instead of a map. I couldn't figure out a nice way of doing it with Dart 2

Another possible Dart-ish approach could be to have the container to generate the Factory class based on annotations, like for instance Guice does

Hello, in my opnion, this approach creates a tight coupling between the IoC container and object creation. Instead of injecting a function with dynamic parameters, why not register a factory in the container? That way, the container resolves the factory, and the factory handles object creation with the required parameters. This keeps the DI setup cleaner and avoids unnecessary complexity.

for example

final factory = container.resolve<MyServiceFactory>();
final service = factory.create("123", 5)

or you can register a builder

final builder = container.resolve<MyServiceBuilder>();
final myService = builder
    .setId("123")
    .setCount(5)
    .build();

@kalymero

kalymero commented Mar 28, 2025

Copy link
Copy Markdown
Author

@gbtb16 have pushed a commit to show how, updating to Dart >= 3.0.0, the Records can be leveraged to keep typesafety.

In particular then, if you want assisted injection, you may:

  • define the type for the args to be injected with assistance
typedef SithAssistedParameters = ({String id});
  • register the assisted factory for the type S and parameters P
container.registerAssistedFactory<Sith, SithAssistedParameters>((c) {
    return (SithAssistedParameters args) =>
        Sith('Sheev', 'Palpatine', args.id);
  });
  • resolve the assisted injector for the type S and parameters P and use it
final Sith sith =
    container.resolve<AssistedInjector<Sith, SithAssistedParameters>>()(
        (id: 'DarthSidious'));

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants