Closed siehc closed 5 months ago
Hello @siehc, I dont think I understood you question.
Reflex create one root ProjectContainer
and then scopes it for every new opened scene like the following schema:
graph TD;
ProjectContainer-->SceneOneContainer;
ProjectContainer-->SceneTwoContainer;
ProjectContainer-->SceneThreeContainer;
With this schema in mind, you wanted to create a scope from which container? From a scene container or from root ProjectContainer
?
If SceneTwo is opened by SceneOne I want SceneTwoContainer to inherit from SceneOneContainer instead of ProjectContainer
@siehc No, thats not possible, and also I do not recommend. Unity scenes implementation theres no hierarchy, so theres no guarantee that, for instance, scene two, opened by scene one, will be disposed once scene one is disposed. As scenes are a flat hierarchy, not a tree.
Howerver what most people do, even I, is to pre inject a scene using ReflexSceneManager.PreInstallScene
with what you need. Most people used it for creating boot
scenes, a scene that prepare all needed services for a complete session
scene.
You can see a simple example of that in https://github.com/gustavopsantos/Reflex?tab=readme-ov-file#-getting-started, at step 18.
But singletons must be prepared in the ProjectContainer
instead of the BootScene
, otherwise they cannot be shared across scenes, right?
graph TD;
ProjectContainer-->SceneLoginContainer;
SceneLoginContainer-->SceneLobbyContainer;
SceneLobbyContainer-->SceneShopContainer;
SceneLobbyContainer-->SceneSettingContainer;
I think there are some pros here.
No need to maintain many PreInstallScene
.
Most objects or services injected by DI are used by more than one scene.
If scene scope could inherit from parent scene scope, then we can maintain minimal PreInstallScene
.
In my case, most objects and services could just be prepared in SceneLobbyContainer
.
Easy to clean up singletons.
For instance, in a logout scenario, it's easier to clean up when most objects and services that need to be cleared are prepared in SceneLobbyContainer
. You just close all scenes and return to SceneLogin
. However, if objects or services are prepared by ProjectContainer
, we have to clear them manually.
Although I can maintain the scene hierarchy by myself, the lack of inheritance from parent scopes makes it less enjoyable to use Reflex. :persevere:
But singletons must be prepared in the
ProjectContainer
instead of theBootScene
, otherwise they cannot be shared across scenes, right?
If a singleton object is constructed at SceneLogin
scene and injected to SceneLobbyContainer
using PreInstallScene
, and then you scope SceneShopContainer
from SceneLobbyContainer
, the singleton object will be only disposed when the owner container is disposed (SceneLobbyContainer). In another words, inherited bindings are never disposed by the container, only self/owned bindings, allowing for children containers to be disposed without affecting parent life cycle.
@siehc One thing you can do (havent tested but I think it can be done) is to create a method that opens a scene "from another" scene, forcing this container hierarchy you want.
You will have to use PreInstallScene
functionality and also reflection to get container.ResolversByContract
but since its a property, you can reflect it once and create a GetDelegate for really fast get invokes.
@siehc What you can also do is to change reflex internals to your needs, check UnityInjector::CreateSceneContainer
on how scene containers are created, here you can change from which container the scene container are being scoped.
I'll be also thinking in how reflex can be updated to safely allow scene container inheritance as a opt-in change, so it does not break for other users if I decide to push it.
@siehc Just to let you know, Im working in a solution do allow you to control scene parent containers as a opt-in feature. Its already working however I need to do some more tests to ensure everything else kept working as it was.
@siehc See lastest release, it has the feature you need, https://github.com/gustavopsantos/Reflex/releases/tag/8.5.0
Hi Is it possible to inherit scope from the parent scene instead of the root scope? This would allow me to avoid placing too many singleton objects in the root scope.