Filip-Drabinski / Godot.DependencyInjection

Godot.DependencyInjection
MIT License
53 stars 6 forks source link

[Docs/Feedback] Injected members are unusable at `_on_ready` #9

Open Fernthedev opened 1 year ago

Fernthedev commented 1 year ago

DependencyInjectionManagerNode injects all nodes at the Ready stage.

This is called first to children, then to their parents. Because of this, all nodes have their fields set to null even if the services are defined properly.

Not entirely sure what's the intended way of doing this, maybe you thought we should use this instead. Regardless, seems pretty easy to solve.

[Inject]
public void _ReadyInject() {}
Unrelated but would be nice to have more Node dependency support, similar to how Zenject for Unity works. E.g adding nodes existing in the scene tree to the ServiceCollection automatically, their interfaces etc. I made my own solution which adds nodes in the tree implementing `IServiceNode` to the service collection.

Edit: The workaround shown above won't work for injected fields or properties. Fields and properties are not injected at the time the [Inject] method is called, but parameters are.

Filip-Drabinski commented 1 year ago

I'm still learning English, so I apologize for not fully understanding what you meant. Could you provide me with an example project that showcases the exact use case causing the issues you mentioned?

About the second issue, I don't actually support node dependency in my design. I think it's better to use other patterns, like a 'provider' with instances set up when nodes start. If you can show me a case where my approach doesn't work, I'll consider adding what you're suggesting.

Fernthedev commented 1 year ago

Alright, so specifically the tree goes like this:

Autoload injects fields, dependencies etc. at the ready stage, which goes like this: (more or less)

So if Node3-a depends on a service on either _EnterTree or _Ready, none of the dependencies will be injected. Why? Ready is called first to children, then to parents. _EnterTree on the other hand is earlier and more importantly is called first by parents then children.

So using _EnterTree as an injection call would result in this order, which would allow the dependencies to be fulfilled:

For the other comment, mind showing a quick-dirty example of what a provider would be? I'm used to Unity so I'm still learning how to structure Godot nodes and such and I wouldn't mind being inspired :)

Filip-Drabinski commented 1 year ago

I have partially addressed your issue in #20. In my testing, services were already accessible in _Ready. Perhaps there was an issue with your configuration. I'm slowly working on test godot project showcasing how I configure DI. Unfortunately, I couldn't find a way to make services available in_EnterTree for the nodes added with AddChild, so the current solution will only work for the initial nodes in the scene