VContainer icon indicating copy to clipboard operation
VContainer copied to clipboard

VContainer events not firing for Scoped/Transient

Open YegorStepanov opened this issue 3 years ago • 3 comments

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

        builder.RegisterEntryPoint<Entry>();
    }

    private class Entry : IStartable
    {
        public Entry(Component1 c) { }

        public void Start() { }
    }
}

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;

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

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

        builder.RegisterEntryPoint<Entry>();
    }

    private class Entry : IStartable
    {
        public Entry(Component1 c) {}

        public void Start() { }
    }
}

public class Component1: IInitializable, IStartable, IDisposable
{
    private LifetimeScope _lifetimeScope;

    public Component1(LifetimeScope s)
    {
        _lifetimeScope = s;
        Debug.Log("ctor " + _lifetimeScope.GetType().Name);
    }

    public void Initialize() => Debug.Log("init " + _lifetimeScope.GetType().Name);
    public void Start() => Debug.Log("start " + _lifetimeScope.GetType().Name);
    public void Dispose() => Debug.Log("dispose " + _lifetimeScope.GetType().Name);
}

1)

//root
builder.Register<Component1>(Lifetime.Scoped).AsSelf().AsImplementedInterfaces();
//scene1

//scene2

VContainer events are called only in the root:

Result:

ctor RootScope
init RootScope
ctor Scene1Scope
start RootScope
ctor Scene2Scope
dispose Scene2
dispose Scene1
dispose Root1

Missing:

init Scene1Scope
init Scene2Scope
start Scene1Scope
start Scene2Scope

Should be:

ctor RootScope
init RootScope
ctor Scene1Scope
-init Scene1Scope
start RootScope
-start Scene1Scope
ctor Scene2Scope
-init Scene2Scope
-start Scene2Scope
dispose Scene2
dispose Scene1
dispose Root1

2)

//root
builder.Register<Component1>(Lifetime.Transient).AsSelf().AsImplementedInterfaces();
//scene1

//scene2

Result:

ctor RootScope
init RootScope
ctor RootScope
ctor RootScope
ctor Scene1Scope
start RootScope
ctor Scene2Scope

It creates 3 RootScope object.

VContainer version : master

YegorStepanov avatar Aug 20 '22 20:08 YegorStepanov

Updated it too.

YegorStepanov avatar Aug 21 '22 15:08 YegorStepanov

Thanks for the report. This is strange behavior. I will investigate.

hadashiA avatar Sep 14 '22 02:09 hadashiA

📝 The problem is that ContainerLocal<T> does not consider Lifetime and does not look for the parent scope. Perhaps LifeTime.Scoped/Lifetime.Transient should follow the parent, even when wrapped in ContainerLocal<T>.

hadashiA avatar Sep 20 '22 06:09 hadashiA

Fixed in #425

hadashiA avatar Nov 05 '22 02:11 hadashiA