Zenject-DynamicObjectInjection is a tool that allows to automatically inject/bind dependencies into the prefabs instantiated at runtime by the standard Unity 3D instantiation flow.
As the additional side product, it's also allow to use all power of Zenject framework in Service Locator Pattern style.
If you want to instantiate a prefab at runtime and have any MonoBehaviour's automatically injected, Zenject framework force you to instantiate game object through factory or using the special DiContainer.InstantiatePrefab method. In most cases, it works fine, but sometimes especially if you use 3d-party solutions, it can become a problem.
This tool solves this problem allowing you to use standard Object.Instantiate method and will ensure any MonoBehaviour's fields that are marked with the [Inject]
attribute are filled in properly, and all [Inject]
methods within the prefab are called as it happens when prefab is instantiated in Zenject recommended way.
As an addition, this tool automatically binds all components configured in ZenjectBinding
MonoBehaviour attached to the instantiated prefabs.
To inject dependencies in runtime instantiated prefab you only need to add a ZenjectDynamicObjectInjection
MonoBehaviour to the root game object of the prefab.
After instantiating of the prefab, all dependencies will be automatically resolved, by doing a lookup in the most 'local' container towards to the instantiated game object, and injected on Awake() phase before game object MonoBehaviour's will have their Awake() method called.
Moreover if you also need to bind game object MonoBehaviour's to the Zenject container, you can do this by adding a ZenjectBinding
MonoBehaviour to the prefab and configuring it in a usual way.
To install the tool you need to follow next steps:
- Install Zenject framework v5.2.0 or higher.
- Clone this repo and copy the UnityProject/Assets/Plugins/ZenjectDynamicObjectInjection directory to your own Unity3D project.
“Dear Friend, the author fully understands that use of the Service Locator Pattern contradicts ideas of dependency injections but this tool is not positioned as the replacement for the regular Zenject flow but as an opportunity to sometimes cut off a corner and pays more attention to the delivering happiness to players.”
Service could be registered in a project container
public class SomeService : MonoBehaviour, ISomeService
{
private void Awake()
{
ZenjectLocator.Container.Bind<ISomeService>().FromInstance(this).AsSingle();
...
}
...
}
or in the most 'local' container of specified context type to the target scene, game object or component.
public class SomeService : MonoBehaviour, ISomeService
{
private void Awake()
{
ZenjectLocator.GetContainer(this.gameObject).Bind<ISomeService>().FromInstance(this).AsSingle();
...
}
...
}
Similarly to services registration service could be located in a project container
public class Foo : MonoBehaviour
{
private void OnCollisionEnter(Collision collision)
{
ZenjectLocator.Container.Resolve<ISomeService>.PerformTask(this.gameObject);
...
}
}
or in the most 'local' container.
public class Foo : MonoBehaviour
{
private void OnCollisionEnter(Collision collision)
{
ZenjectLocator.GetContainer(collision.gameObject).Resolve<ISomeService>.PerformTask(this.gameObject);
...
}
}
Zenject-DynamicObjectInjection is distributed under the MIT license. Please keep the existing headers.
Developer Alexandr Pereverzev - a.v.pereverzev@gmail.com