Zenject+Netcode spawn problem

Hi all. I am trying to share Zenject and Netcode for Gameobjects, but I ran into problem. To correctly inject dependencies of instantiated objects in Zenject, i need to spawn the prefab not through GameObject.Instantiate, but with the help of

GameObject instance = diContainer.InstantiatePrefab(characterPrefab);

Then all the dependencies of this perfab that use [Inject] will be written correctly.

But the NetworkObject is spawned on the server using the Spawn() command. And on the client, a copy of this object is simply created from the server without the ability to instantiate it through diContainer. And dependencies written with [Inject] are not created.

How in Zenject reinject dependencies for objects that for some reason already exist in the scene and were not created using diContaner? For example, like these NetworkObjects on client created by the server. Or is it possible to somehow override how objects are created on the client so that they use diContainer?

Hey, use this:

I have the same trouble. I can't inject dependencies to instantiated NetworkObjects. And registering INetworkPrefabInstanceHandler does not work in the host mode. Documentation says that I have to use RegisterHostGlobalObjectIdHashValues instead handlers. But this cannot help me with injection.
I have a partial solution. I created MonoBehaviour which injects its gameObject in Awake method and attached this MonoBehaviour to each GameObject. But there is unresolved question how to specify injecting context right.

this doesn’t work.

“NetworkManager.Singleton.PrefabHandler.AddHandler(prefab, new PooledPrefabInstanceHandler(prefab, this));”

this line gives error.

You might have some luck using the ZenAutoInjector component. From the docs:

I think it uses a similar problem as an example.

We've added a helper MonoBehaviour that you can add to these kinds of objects called ZenAutoInjecter. If you add this MonoBehaviour to your prefab, then you should be able to call GameObject.Instantiate and injection should happen automatically.

After adding this component you might notice that there is a field on it called 'Container Source'. This value will determine how it calculates which container to use for the injection and has the following options:

SearchInHiearchy - This will find the container to use by searching the scene hierarchy where the prefab is instantiated. So if the prefab is instantiated underneath a GameObjectContext, it will use the container associated with the GameObjectContext. If it is instantiated underneath a DontDestroyOnLoad object, then it will use the ProjectContext container. And otherwise will use the SceneContext container for whatever scene it is instantiated in.

SceneContext - Don't bother searching the hierarchy and instead just always use the current SceneContext container.

ProjectContext - Don't bother searching the hierarchy and instead just always use the ProjectContext container.

If that doesn't work for some reason, you may have some luck with using BindAsync https://github.com/modesttree/Zenject/blob/master/Documentation/Async.md

Another strategy might be toggling the contexts autorun to off, and then once the object is asynchronously created, you can bind the instance and run the dependency injection.

1 Like

Not sure how bad this solution is, but it works for me to use:
Make factory class, that instantiate Prefab with NetworkObject and call ProjectContext.Instance.Container.InjectGameObject(intantiatedPrefab) or just use
ProjectContext.Instance.Container.InjectGameObject(gameObject) in Awake message of my NetworkBehaviour