Skip to content

When using Container.Instantiate to create a new object in the Create method of the factory, IMemoryPool is not assigned. #287

@CyberHamburg

Description

@CyberHamburg

Describe the bug
When simultaneously using PlaceholderFactory and IPoolable, if you override the Create method of PlaceholderFactory and create instances using Container.Instantiate instead of base.Create(), it will result in the IMemoryPool instance not being assigned. However, if you create instances using base.Create(), it will be correctly assigned.

To Reproduce
Code here:

public enum TestType
{
    Base,
    Son
}

public class Base : IPoolable<TestType, IMemoryPool>, IDisposable
{
    private IMemoryPool pool;
    internal TestType type;

    public void OnDespawned()
    {
        pool = null;
    }

    public void OnSpawned(TestType p1, IMemoryPool p2)
    {
        pool = p2;
        type = p1;
    }


    public void Dispose()
    {
        pool.Despawn(this);
    }

    public class TestFactory : PlaceholderFactory<TestType, Base>
    {
        public DiContainer Container;

        public TestFactory(DiContainer container)
        {
            Container = container;
        }

        public override Base Create(TestType type)
        {
            Base baseClass;

            switch (type)
            {
                case TestType.Base:
                    baseClass = Container.Instantiate<Base>();
                    Debug.Log(baseClass.pool == null);
                    baseClass.type = TestType.Base;
                    break;
                case TestType.Son:
                    Son other = Container.Instantiate<Son>();
                    other.type = TestType.Son;
                    baseClass = other;
                    break;
                default:
                    throw new ArgumentOutOfRangeException(nameof(type), type, null);
            }

            return baseClass;
        }
    }
}


public class Son : Base
{

}
public class TestBinder : MonoInstaller
{
    public override void InstallBindings()
    {
        Container.BindFactory<TestType, Base, Base.TestFactory>().FromPoolableMemoryPool(x => x.WithInitialSize(5));
    }
}
public class TestMono : MonoBehaviour
{
    public Son Son;
    private Base.TestFactory factory;

    [Inject]
    public void Initialization(Base.TestFactory factory)
    {
        this.factory = factory;
    }

    private void Start()
    {
        Base temp = factory.Create(TestType.Base);
        temp.Dispose(); //throw NullReferenceException here because pool is null
    }
}

Expected behavior
How can I temporarily mitigate the impact of this issue? My project requires both a memory pool and the Create() method of the factory. While solely using the memory pool and not the factory might avoid this problem, I'm personally not fond of directly using memory pools. It would be preferable to have a better solution.

Extenject and Unity info (please complete the following information):

  • Zenject version: 9.2.0
  • Unity version: 2020.3.24.f1
  • Project's scripting backend: Mono

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions