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

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

Open
CyberHamburg opened this issue Mar 22, 2024 · 0 comments

Comments

@CyberHamburg
Copy link

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
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