-
Notifications
You must be signed in to change notification settings - Fork 22
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
Come up with an API that will allow injecting values in bindings based on lambda functions using local variables #61
Comments
The API should be based on this interface, so that it would be possible to distinguish calls from custom lambda function logic belonging to the binding. |
My idea comes from the usage of Unity DI. There is a concept of constructor override and dependency override. https://www.tutorialsteacher.com/ioc/overrides-in-unity The idea is to replace a specific constructor parameter for which you don’t have a registration, or you have a registration but in this particular resolve, you want to use a specific value for a type that is different from the registered one. DependencyOverride works not only for the class you currently resolve but also for all dependencies down the dependency tree that have that dependency type in their constructors. As the name suggests, it overrides all dependencies down the dependency tree. I can guess that the latter will be complex to implement. ParameterOverride should be easy to implement—it overrides just a single parameter from the list of parameters of the constructor by matching the parameter name. With reflection-based DI, that approach was very fragile, and I was cautious to use it because if someone renames the parameter, you lose your override and you don’t get any errors indicating the problem. With a source generator, this can be made very durable and have a compile-time error if ParameterOverride doesn’t match a constructor parameter name or type. Having this, you can pass a specific constructor parameter without the need to specify the others, as they can be picked up from known registrations. This is very convenient because when you add more parameters to the constructor, you won’t need to update the registration code if you already have this type registered. |
@ekalchev could you please review the approach in the examples Tag on injection site and |
DI.Setup(nameof(Composition))
.Bind(Tag.On("*Service:dependency1", "*Consumer:myDep"))
.To<AbcDependency>()
.Bind(Tag.On("*Service:dependency2", "*Service:Dependency3"))
.To<XyzDependency>()
.Bind().To<Consumer<TT>>()
.Bind<IService>().To<Service>() Isn't it better to annotate somehow those registration with dependency override syntax
instead of annotating the constructor argument types? .Bind<IDependency>("mydep").To<XyzDependency>()
.Bind().To<Consumer<TT>>().DependencyOverride<IDependency>("mydep") if you want to override constructor parameter by name .Bind<IDependency>("mydep1").To<XyzDependency>()
.Bind<IDependency>("mydep2").To<AbcDependency>()
.Bind().To<Service>()
.ConstructorParameterOverride("dependency1", "mydep1")
.ConstructorParameterOverride("dependency2", "mydep2") I believe this syntax is easy to understand and when you inspect an type registration you immediately can spot overrides to a specific type or constructor argument. |
Idea suggested by @ekalchev here.
The text was updated successfully, but these errors were encountered: