VContainer icon indicating copy to clipboard operation
VContainer copied to clipboard

Root scope creates objects in the Scene scope

Open YegorStepanov opened this issue 3 years ago • 1 comments

Template
public class RootScope : LifetimeScope
{
    protected override void Configure(IContainerBuilder builder)
    {
        //root

        builder.RegisterEntryPoint<Entry>();
    }

    private class Entry : IStartable
    {
        public Entry(Component1 c) =>
            Debug.Log($"scene is '', gameObject scene is: {c.gameObject.scene.name} name={c.name}");
        
        public void Start() { }
    }
}

//scene1.scene
public class Scene1Scope : LifetimeScope
{
    protected override void Configure(IContainerBuilder builder)
    {
        //scene1

        builder.RegisterEntryPoint<Entry>();
    }

    private class Entry : IStartable
    {
        private readonly LifetimeScope _scope;

        public Entry(LifetimeScope scope, Component1 c)
        {
            _scope = scope;
            Debug.Log($"scene='scene1' goScene={c.gameObject.scene.name} goName={c.name}");
        }

        public void Start()
        {
            using (LifetimeScope.EnqueueParent(_scope))
                SceneManager.LoadScene("scene2", LoadSceneMode.Additive);
        }
    }
}

//scene2.scene
public class Scene2Scope : LifetimeScope
{
    protected override void Configure(IContainerBuilder builder)
    {
        //scene2

        builder.RegisterEntryPoint<Entry>();
    }

    private class Entry : IStartable
    {
        public Entry(Component1 c) =>
            Debug.Log($"scene='scene2' goScene={c.gameObject.scene.name} goName={c.name}");

        public void Start() { }
    }
}

public sealed class Component1 : MonoBehaviour { }

1)

//root
builder.RegisterComponentOnNewGameObject<Component1>(Lifetime.Singleton, "root0");
//scene1
builder.RegisterComponentOnNewGameObject<Component1>(Lifetime.Singleton, "root1");
//scene2
builder.RegisterComponentOnNewGameObject<Component1>(Lifetime.Singleton, "root2");

Result:

scene=''       goScene=scene1 goName=root0
scene='scene1' goScene=scene1 goName=root1
scene='scene2' goScene=scene2 goName=root2

Should be:

scene=''       goScene=''     goName=root0
scene='scene1' goScene=scene1 goName=root1
scene='scene2' goScene=scene2 goName=root2

2)

//root
builder.RegisterComponentOnNewGameObject<Component>(Lifetime.Transient/Scoped, "root0");
//scene1

//scene2

Result:

scene=''       goScene=scene1 goName=root0
scene='scene1' goScene=scene1 goName=root0
scene='scene2' goScene=scene2 goName=root0

Should be:

scene=''       goScene=''     goName=root0
scene='scene1' goScene=scene1 goName=root0
scene='scene2' goScene=scene2 goName=root0

builder.RegisterComponentInNewPrefab() gives the same results.

VContainer version : master

YegorStepanov avatar Aug 20 '22 20:08 YegorStepanov

The results are different today, maybe I hit https://github.com/hadashiA/VContainer/pull/406 Yesterday, each EntryPoint resolves LifetimeScope as Root and spawns 1 object instead 3. Today it works correctly. I've updated issue.

Solution to rest of the issue is analogue of https://github.com/hadashiA/VContainer/pull/414:

if(scope.isRoot)
    DontDestroyOnLoad()

YegorStepanov avatar Aug 21 '22 14:08 YegorStepanov

Looks like #406 and #414 have been merged, so I'll close this.

hadashiA avatar Feb 02 '23 16:02 hadashiA