ssannandeji / Zenject-2019

Dependency Injection Framework for Unity3D
MIT License
2.53k stars 366 forks source link

Inject not called for all gameobjects in the scene in in 8.0.0 and/or Unity 2019.1.7f1 anymore #638

Closed NoxMortem closed 5 years ago

NoxMortem commented 5 years ago

For some reason inject is not detected anymore

using UnityEngine;
using Zenject;

namespace Presentation.Views.Layers
{
    public class Testasf : MonoBehaviour

    {
        [Inject]
        public void Test()
        {
            Debug.Log("ASDF");

        }
    }
}

grafik

The gameobjects are active. Inject is called and ASDF Is logged when the MonoBehaviour is on

but is not called if it is on

but it is called if I create a new GameObject below UI and move the component there...

NoxMortem commented 5 years ago

Reason: A NullReferenceException happened during a GameObject injection earlier in the tree because of the usage of [InjectOptional] on a primitive int.

However, as injection is a rather blackboxed thing I do recommend to increase the amount of logging information if an exception happens during injection.

Before

/*DiContainer.cs:1494*/
method.Action(injectable, paramValues);

Recommended

try
{
    method.Action(injectable, paramValues);
}
catch (Exception ex)
{
    Debug.LogError($"{ex.Message} during injection:{injectable}, {(paramValues?.Select(o => o?.ToString()?? "<null>")?.Join(",") ?? "<null>")}");
    Debug.LogException(ex);
    throw;
}

The inject method which caused the NullReference

public void Inject([InjectOptional] LayerController layerController, [InjectOptional] int controlsLayer)

Which I expected to work because of:

If the dependency is a primitive type (eg. int, float, struct) then it will be injected with its default value (eg. 0 for ints).

The correct usage of optional Bindings on primitive int

public void Inject([InjectOptional] LayerController layerController, int controlsLayer = 0)