tappeddev / injector

Simple dependency injection for Dart. 💉
Apache License 2.0
77 stars 7 forks source link

[Question]injector whether support GenericType like “List<String>”? #12

Closed Guang1234567 closed 5 years ago

Guang1234567 commented 5 years ago

Hello dev:

injector whether support GenericType like “SomeGenericType<String>”?

injector.registerDependency <SomeGenericType<String>>((i) => new SomeGenericType("Hello"));

thanks.

JulianBissekkou commented 5 years ago

Hello,

I am not sure if I understood the question correctly. 🤔 However, you are able to register dependencies with a generic type.

so of course injector.registerDependency<List<String>>(...) works as long as you are requesting the dependency with the exact same type. injector.getDependency<List<String>>();.

another example would be something like this:

injector.registerDependency<Iterable<String>>((_) => <String>["Clear", "now?"]); or

_injector.registerDependency<Repository<User>>((_) => MemoryRepository<User>());

Let me know if you still have some questions!

Guang1234567 commented 5 years ago

@JulianBissekkou

Thanks your reply. ^_^

I also have another question like below:

I register two Car by the injector, but how togetDependency<Car> them separately?

// the first  car instance
injector.registerDependency<Car>((injector) {
      var engine = injector.getDependency<Engine>();
      var fuel = injector.getDependency<Fuel>();
      var driver = injector.getDependency<Driver>();

      return CarImpl_01(engine,fuel,driver);
    });

//  the second car instance
 injector.registerDependency<Car>((injector) {
          var engine = injector.getDependency<Engine>();
          var fuel = injector.getDependency<Fuel>();
          var driver = injector.getDependency<Driver>();

          return CarImpl_02(engine,fuel,driver);
        });
JulianBissekkou commented 5 years ago

Currently, this is not possible and I wonder what use case you have for that 🤔 ?

However, I thought about implementing some kind of "Tag-Feature". You could register a dependency on a specific tag. This could look something like this:

injector.registerDependency<Car>("gasoline", (injector) {
      var engine = injector.getDependency<Engine>();
      var fuel = injector.getDependency<Fuel>();
      var driver = injector.getDependency<Driver>();

      return GasolineCar(engine, fuel, driver);
    });

    injector.registerDependency<Car>("electric", (injector) {
      var engine = injector.getDependency<ElectricEngine>();
      var driver = injector.getDependency<Driver>();

      return ElectricCar(engine, driver);
    });

Would this be helpful? Let me know! 👍

Guang1234567 commented 5 years ago

“Tag-Feature” is very useful for product variants. (https://developer.android.com/studio/build/build-variants).

For example:

In free version, we provide GasolineCar; In paid version, we provide ElectricCar.

thanks.

Guang1234567 commented 5 years ago

In addition, i thought about Injector maybe not singleton like below:

https://github.com/tikkrapp/injector/blob/40d2acae24037dc32e30b07561ab4a4b5d58be9c/lib/src/injector_base.dart#L13-L24

Because i used to use goolge/dagger2 in android before dart. Sometimes our App lifecycle may spilt into three scope like AppScope, UseScope and ActivityScope that corresponding to the AppScopeInjector, UserScopeInjector and ActivityInjector.

For example:

UserScopeInjector will be disposed when the logined user was changed. And UserScopeInjector maybe depends on AppScopeInjector like below:


class Car {
  final Energy _energy;

 Car(this._energy);
}

appScopeInjector.registerDependency<Energy>("gasoline", (injector) {
      return Gasoline();
    });

userScopeInjector.registerDependency<Car>((injector) {
      return Car(appScopeInjector.getDependency<gasoline>(););
    });
JulianBissekkou commented 5 years ago

if you want to register different dependencies based different conditions (free or paid in your case) I would then do the following stuff:


if(isPaidVersion) {
   _registerPaidDependencies(injector);
}
else {
    _registerFreeDependencies(injector);
}

This is not the most elegant solution tbh... 🤔
I thought about creating containers for a group of dependencies. so you would be able to create a container with all your "paid" dependencies and a container with all your "free" dependencies.

However, the scope feature is something that could be a bit more work to do. I created an issue for this specific feature. It would be super nice if you can provide some more details on how you would structure the API. I have some ideas in mind and I will write them down tomorrow.

JulianBissekkou commented 5 years ago

Here is the issue for the scope feature. https://github.com/tikkrapp/injector/issues/13

Add your ideas or feature requests if you want! 👍 I will start the draft tomorrow and keep you updated. Any other questions or feature ideas?