Skip to content
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

Registering and Resolving not executed when LifetimeScope parent not found #644

Open
Maesla opened this issue Mar 13, 2024 · 0 comments
Open

Comments

@Maesla
Copy link

Maesla commented Mar 13, 2024

If a LifetimeScope defines a parent and the parent is not found, neither a exception is thrown nor registering and resolving is executed

LifetimeScope executes in its Awake GetRuntimeParent(), which does throw a VContainerParentTypeReferenceNotFound.
However, this exception is silently handled by the Awake's try catch here and added to a waiting list.

The resulting behavior is that, when you run a scene with a LifetimeScope with a parent defined, and the parent is not found, you don't get any error or exception and you don't get neither any registering nor injection

Video

2024-03-13.12-49-27.mp4

Test

using NUnit.Framework;
using System.Collections;
using UnityEngine;
using UnityEngine.TestTools;
using VContainer;
using VContainer.Tests.Unity;
using VContainer.Unity;

public class ParentNotFoundExceptionTest
{

    private class Foo
    {
        public int value;

        public Foo()
        {
            this.value = -1;
        }
    }

    private class TestLifeTimeScope : LifetimeScope
    {
        public bool buildCallbackCalled = false;
        public bool configureCalled = false;

        protected override void Awake(){} //empty to do nothing in AddComponent


        //like awake, but on demand
        public void Init()
        {

            // this method calls to base.Awake()
            // base.Awake() calls to Build
            // Build to GetRuntimeParent
            // GetRuntimeParent throws VContainerParentTypeReferenceNotFound
            // The exception is handled in the Awake again without rethrowing
            base.Awake(); 
        }

        protected override void Configure(IContainerBuilder builder)
        {
            configureCalled = true;

            builder.RegisterBuildCallback(container =>
            {
                buildCallbackCalled = true;
            });

            builder.Register<Foo>(Lifetime.Scoped);
        }
    }


    [UnityTest]
    public IEnumerator VContainerParentTypeReferenceNotFoundTest()
    {
        GameObject go = new GameObject("TestLifeTimeScope");
        TestLifeTimeScope testLifetimeScope = go.AddComponent<TestLifeTimeScope>();
        testLifetimeScope.autoRun = true;

        testLifetimeScope.parentReference = ParentReference.Create<SampleChildLifetimeScope2>();


        bool exceptionThrown = false;
        try
        {
            testLifetimeScope.Init();
        }
        catch (VContainerParentTypeReferenceNotFound) //parent doesn't exist, so the exception should be thrown
        {
            exceptionThrown = true;
        }


        ////Expected 1. Exception thrown and registering and injection not done
        //Assert.That(exceptionThrown, Is.True, "Exception not thrown");
        //Assert.That(testLifetimeScope.buildCallbackCalled, Is.False, "Build Callback not called");
        //Assert.That(testLifetimeScope.configureCalled, Is.False, "Configure called");
        //Assert.Throws<System.NullReferenceException>(() => testLifetimeScope.Container.Resolve<Foo>());

        ////Expected 2. Exception not thrown and registering and injection done
        //Assert.That(exceptionThrown, Is.False, "Exception not thrown");
        //Assert.That(testLifetimeScope.buildCallbackCalled, Is.True, "Build Callback not called");
        //Assert.That(testLifetimeScope.configureCalled, Is.True, "Configure called");
        //Assert.DoesNotThrow(() => testLifetimeScope.Container.Resolve<Foo>());

        //Current Behavior
        Assert.That(exceptionThrown, Is.False, "Exception not thrown");
        Assert.That(testLifetimeScope.buildCallbackCalled, Is.False, "Build Callback not called");
        Assert.That(testLifetimeScope.configureCalled, Is.False, "Configure called");
        Assert.Throws<System.NullReferenceException>(() => testLifetimeScope.Container.Resolve<Foo>());


        yield return null;
    }
}

Scene Test

ParentNotFound.zip

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant