ssannandeji / Zenject-2019

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

Inject reference of a monobehaviour to an instantiated gameobject #674

Closed SplunkyDev closed 4 years ago

SplunkyDev commented 4 years ago

I have a GameSystemIntsaller which contains a prefab to be instantiated `using UnityEngine; using Zenject;

public class GameSystemInstaller : MonoInstaller {

public GameObject m_gPrefabEnemy;

public override void InstallBindings()
{
    Container.BindInterfacesTo<EnemyManagement>().FromComponentInHierarchy().AsSingle();
    Container.BindFactory<int,EnemyIdentity, EnemyIdentity.Factory>().FromComponentInNewPrefab(m_gPrefabEnemy);
}

}`

The prefab contains EnemyIdentity and EnemyDeath `using UnityEngine; using Game.Utils; using Zenject;

public class EnemyIdentity : MonoBehaviour, IEntityIdentification { [SerializeField] private int m_iID; public int ID { get => m_iID; private set => m_iID = value; } public int Path { get => Path; set => Path = value;}

[Inject]
public void Construct(int a_iID)
{
    ID = a_iID;
}

[SerializeField]
private eTypeOfEntity m_enumTypeOfEntity;
public eTypeOfEntity EnumTypeOfEntity { get => m_enumTypeOfEntity; private set => m_enumTypeOfEntity = value; }

public class Factory : PlaceholderFactory<int, EnemyIdentity> { }

}`

Now the prefabs getting instantiated with the correct ID's by EnemyManagement `using System.Collections.Generic; using UnityEngine; using System; using Zenject; public class EnemyManagement : MonoBehaviour, IEnemyContainer { EnemyIdentity.Factory _enemyFactory;

[Inject]
public void Construct(EnemyIdentity.Factory a_enemyfactory)
{
    m_iIDGenerate = 0;
    _enemyFactory = a_enemyfactory;

    Initialize();
}

private Dictionary<int, IEntityIdentification> m_dicEntityContainer = new Dictionary<int, IEntityIdentification>();
private int m_iIDGenerate = 0;

private Action m_delEnemy;

public void RegisterEvent(Action a_Action)
{
    m_delEnemy += a_Action;
}

public void DeregisterEvent(Action a_Action)
{
    m_delEnemy -= a_Action;
}

private void Initialize()
{

    while (m_iIDGenerate < 3)
    {
        m_iIDGenerate++;
        IEntityIdentification entityIdentification = _enemyFactory.Create(m_iIDGenerate);
        AddEnemyIntoContainer(entityIdentification);
    }

}

public void AddEnemyIntoContainer(IEntityIdentification a_entityIdentification)
{
    if(!m_dicEntityContainer.ContainsKey(a_entityIdentification.ID))
    {
        m_dicEntityContainer.Add(a_entityIdentification.ID, a_entityIdentification);
    }

}

public void RemoveEnemyIntoContainer(IEntityIdentification a_entityIdentification)
{
    if (m_dicEntityContainer.ContainsKey(a_entityIdentification.ID))
    {
        m_dicEntityContainer.Remove(a_entityIdentification.ID);
    }
}

} `

My Enemy Preab also contains EnemyDeath which implements IEntityDestroy , I want to inject EnemyManagement into EnemyDeath `using UnityEngine; using Zenject; public class EnemyDeath : MonoBehaviour, IEntityDestroy { public IEnemyContainer EntityContainer { get => EntityContainer; private set => EntityContainer = value; } public IEntityIdentification EntityIdentification { get => EntityIdentification; private set => EntityIdentification = value; }

void Awake()
{
}

public void construct(IEnemyContainer a_enemyContainer)
{
    Debug.Log("[EnemyDeath] EnemyContainer ref");
    EntityContainer = a_enemyContainer;
    EntityIdentification = GetComponent<IEntityIdentification>();       //Getting it from self gameobject
}

public void DestroySelf()
{
    EntityContainer.RemoveEnemyIntoContainer(EntityIdentification);
}

}`

I have added Inject to the Construct Method Of EnemyDeath I get an ERROR: StackOverflowException: The requested operation caused a stack overflow.

I am new to Dependency Injection, found Zenject a very popular IoC thought of following SOLID principles using ZENJECT.

Could anyone point me in the right direction? I am kinda lost here. My game object will have many classes as I am following the principles of SOLID, what I want to do is inject the dependencies to all the classes that have dependencies, here my EnemyDeath wants to kill itself but first needs to remove itself from the EnemyManagement dictionary

SplunkyDev commented 4 years ago

It was the issue with my properties not with the zenject public IEnemyContainer EntityContainer { get; private set; }