Zenject icon indicating copy to clipboard operation
Zenject copied to clipboard

Passing data to prefab created by factory, using game object context

Open novalain opened this issue 4 years ago • 4 comments

Describe the bug When using PrefabFactory or InstantiatePrefabForComponent through a custom factory, the framework implies that additional data can be passed to the facade/installer. However, if the object contains a game object context, Zenject failes to resolve the passed parameters.

To Reproduce

  1. Make a binding like Container.BindFactory<UnityEngine.Object, float, MyFacade, MyFacade.Factory>().FromFactory<PrefabFactory<float, MyFacade>>();
  2. Pass the data on creation myFactory.Create(prefab, 2f)
  3. Zenject fails to resolve the float if the given prefab has a game object context attached.

Steps to reproduce the behavior:

Expected behavior Data can be passed dynamically to prefab factories or custom factories that get a prefab at run time.

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

  • Zenject version: 9.2.0
  • Unity version: 2020.3.9f1
  • Project's scripting backend [e.g. Mono/IL2CPP] Editor

Additional context Noticed that doing the binding like:

Container.BindFactory<float, MyFacade, MyFacade.Factory>().FromSubContainerResolve().ByNewContextPrefab(...)

makes it work. However in our case it's not good enough, as we want to pass the prefab (and the data) along in run time.

novalain avatar Jun 07 '21 15:06 novalain

Hey any solution to this issue? I have the exact same requirement

nipunasudha avatar Jun 03 '22 16:06 nipunasudha

Describe the bug When using PrefabFactory or InstantiatePrefabForComponent through a custom factory, the framework implies that additional data can be passed to the facade/installer. However, if the object contains a game object context, Zenject failes to resolve the passed parameters.

To Reproduce

  1. Make a binding like Container.BindFactory<UnityEngine.Object, float, MyFacade, MyFacade.Factory>().FromFactory<PrefabFactory<float, MyFacade>>();
  2. Pass the data on creation myFactory.Create(prefab, 2f)
  3. Zenject fails to resolve the float if the given prefab has a game object context attached.

Steps to reproduce the behavior:

Expected behavior Data can be passed dynamically to prefab factories or custom factories that get a prefab at run time.

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

  • Zenject version: 9.2.0
  • Unity version: 2020.3.9f1
  • Project's scripting backend [e.g. Mono/IL2CPP] Editor

Additional context Noticed that doing the binding like:

Container.BindFactory<float, MyFacade, MyFacade.Factory>().FromSubContainerResolve().ByNewContextPrefab(...)

makes it work. However in our case it's not good enough, as we want to pass the prefab (and the data) along in run time.

+1 I have the same issue

adrianyip-1222 avatar Aug 16 '22 14:08 adrianyip-1222

+1 I need exactly this feature, same problem.

lucid-dreamm avatar Jan 06 '23 21:01 lucid-dreamm

It's possible to pass data into a prefab's GameObjectContext via a factory using this code:

public GameObject facadePrefab

public override void InstallBindings()
{
    Container.BindFactory<TestData, Facade, Facade.Factory>()
        .FromSubContainerResolve()
        .ByNewPrefabInstaller<FacadeInstaller>(facadePrefab);
}

The FacadePrefab most have the following components attached to it:

  • GameObjectContext
  • Facade MonoBehaviour
  • ZenjectBinding (bound to the Facade)
  • MonoInstaller

The MonoInstaller must bind it's data in this way

[InjectOptional]private TestData data = new TestData();

public override void InstallBindings()
{
    Container.BindInstance(data)
}

When the facadePrefab is created via Facade.Factory.Create(myTestData), myTestData will be injected into the monoinstaller, and thus into the GameObjectContext.

This works perfectly fine for Factories, but no for MemoryPooled Factories. So far I haven't found a way to Re-inject a gameobject that is spawned via a MemoryPool.

SimonNordon4 avatar Apr 06 '23 10:04 SimonNordon4