Closed ATHellboy closed 11 months ago
Probably it is in this way actually.
https://vcontainer.hadashikick.jp/resolving/container-api
Exactly like Zenject. Just I should replace InstantiatePrefab
with Instantiate
. But because I'm still trying to figure out things in VContainer so I've not gotten the result.
How can I have LifetimeScope
on a prefab when using IObjectResolver.Instantiate
?
Looks like when I use this method, actually it registers LifetimeScope
component too (Because of registering the root gameObject and all the descendents) and it makes an error on the parent which calls instantiating.
The error:
VContainerException: Failed to resolve System.Object : No such registration of type: Character.CharacterContext
VContainer.Internal.ReflectionInjector.InjectMethods (System.Object obj, VContainer.IObjectResolver resolver, System.Collections.Generic.IReadOnlyList`1[T] parameters) (at ./Library/PackageCache/jp.hadashikick.vcontainer@af7bd4ecab/Runtime/Internal/ReflectionInjector.cs:106)
VContainer.Internal.ReflectionInjector.Inject (System.Object instance, VContainer.IObjectResolver resolver, System.Collections.Generic.IReadOnlyList`1[T] parameters) (at ./Library/PackageCache/jp.hadashikick.vcontainer@af7bd4ecab/Runtime/Internal/ReflectionInjector.cs:28)
VContainer.Container.Inject (System.Object instance) (at ./Library/PackageCache/jp.hadashikick.vcontainer@af7bd4ecab/Runtime/Container.cs:220)
VContainer.Unity.ObjectResolverUnityExtensions.<InjectGameObject>g__InjectGameObjectRecursive|0_0 (UnityEngine.GameObject current, VContainer.Unity.ObjectResolverUnityExtensions+<>c__DisplayClass0_0& ) (at ./Library/PackageCache/jp.hadashikick.vcontainer@af7bd4ecab/Runtime/Unity/ObjectResolverUnityExtensions.cs:21)
VContainer.Unity.ObjectResolverUnityExtensions.InjectGameObject (VContainer.IObjectResolver resolver, UnityEngine.GameObject gameObject) (at ./Library/PackageCache/jp.hadashikick.vcontainer@af7bd4ecab/Runtime/Unity/ObjectResolverUnityExtensions.cs:34)
VContainer.Unity.ObjectResolverUnityExtensions.InjectUnityEngineObject[T] (VContainer.IObjectResolver resolver, T instance) (at ./Library/PackageCache/jp.hadashikick.vcontainer@af7bd4ecab/Runtime/Unity/ObjectResolverUnityExtensions.cs:130)
VContainer.Unity.ObjectResolverUnityExtensions.Instantiate[T] (VContainer.IObjectResolver resolver, T prefab, UnityEngine.Vector3 position, UnityEngine.Quaternion rotation, UnityEngine.Transform parent) (at ./Library/PackageCache/jp.hadashikick.vcontainer@af7bd4ecab/Runtime/Unity/ObjectResolverUnityExtensions.cs:117)
This is a partial screenshot from the prefab I'm talking about. (Gameobjects children are not included):
Reproduction project VContainerReproduction.zip
@ATHellboy I'm not sure, maybe I've already encountered this problem, but your case is poorly described. I advise you to write a reproduction.
@ATHellboy I'm not sure, maybe I've already encountered this problem, but your case is poorly described. I advise you to write a reproduction.
Thanks for the reply. I just want to instantiate a prefab which contains LifetimeScope component without throwing any errors. btw, injection is done correctly in debugging process but there is an error about not finding registeration for that injected class too. I'm creating minimal reproduction project for showing the issue. I'll post it here.
@ATHellboy mb this example will help u:
@Bezarius Reproduction project VContainerReproduction.zip
@ATHellboy mb this example will help u:
In one of my tests, I've tried to use CreateChildFromPrefab
from Player LifetimeScope (The prefab just contained CharacterLifetimeScope and Auto Run was disabled) then using IObjectResolver.Instantiate
on Character prefab without CharacterLifetimeScope and then Build
on newly created LifetimeScope which was created by CreateChildFromPrefab
. The resault was no injection at all on the Character and same error.
Is it the same approach like above ?
@ATHellboy my bad, I forgot to show the part with the injection:
@ATHellboy dependency injection occurs at the moment of instantiation before dependencies from CharacterLifetimeScope are resolved. To solve this problem, you need to manually manage this process. Unfortunately, VContainer does not know how to do this out of the box.
@ATHellboy dependency injection occurs at the moment of instantiation before dependencies from CharacterLifetimeScope are resolved. To solve this problem, you need to manually manage this process. Unfortunately, VContainer does not know how to do this out of the box.
Thanks for the reply and all the helps here. Last night I figured out how to inject dependencies in this specific situation by these lines:
LifetimeScope characterLifetimeScope = _lifetimeScope.CreateChildFromPrefab(_characterLifetimeScope);
Transform characterInstance = UnityEngine.Object.Instantiate(_characterPrefab, pos, Quaternion.identity, characterLifetimeScope.transform);
characterLifetimeScope.Build();
But this morning I noticed Awake
and OnEnable
are called before method injection.
So changed that to this:
LifetimeScope characterLifetimeScope = _lifetimeScope.CreateChildFromPrefab(_characterLifetimeScope);
_characterPrefab.gameObject.SetActive(false);
Transform characterInstance = UnityEngine.Object.Instantiate(_characterPrefab, pos, Quaternion.identity, characterLifetimeScope.transform);
characterLifetimeScope.Build();
characterInstance.gameObject.SetActive(true);
_characterPrefab.gameObject.SetActive(true);
Does it make sense ?
@ATHellboy Yes, in general it looks like it is correct. In my example, there are just some specifics, so there is more code and it looks more complicated.
@ATHellboy Yes, in general it looks like it is correct. In my example, there are just some specifics, so there is more code and it looks more complicated.
I just noticed by using UnityEngine.Object.Instantiate
on the prefab which has LifetimeScope
, eveything works correctly. It made me nut tbh. I didn't need to use Factory or generting scope at all. I think it must be mentioned somewhere on doc. It took me so much time to figure it out.
Hey there, Recently I'm trying to replace Zenject with VContainer. Sorry about creating a new issue for asking my question. Unfortunately I couldn't find anywhere to ask my question. Probably there is Discord channel or Gitter group for that ?
anyway, In Zenject, I've implemented factory method and instantiation in this way:
I'm curious to know if I can achieve same thing in Vcontainer ? Probably I should use this ? https://vcontainer.hadashikick.jp/registering/register-factory#registering-factory-methods Or there is another way like accessing container by injection and use methods there like I was using Zenject ?