diff --git a/VContainer/Assets/VContainer/Runtime/Unity/ComponentRegistrationBuilder.cs b/VContainer/Assets/VContainer/Runtime/Unity/ComponentRegistrationBuilder.cs index 2b75f209..1b8cc918 100644 --- a/VContainer/Assets/VContainer/Runtime/Unity/ComponentRegistrationBuilder.cs +++ b/VContainer/Assets/VContainer/Runtime/Unity/ComponentRegistrationBuilder.cs @@ -8,15 +8,15 @@ namespace VContainer.Unity struct ComponentDestination { public Transform Parent; - public Func ParentFinder; + public Func ParentFinder; public bool DontDestroyOnLoad; - public Transform GetParent() + public Transform GetParent(IObjectResolver resolver) { if (Parent != null) return Parent; if (ParentFinder != null) - return ParentFinder(); + return ParentFinder(resolver); return null; } @@ -32,7 +32,7 @@ public void ApplyDontDestroyOnLoadIfNeeded(Component component) public sealed class ComponentRegistrationBuilder : RegistrationBuilder { readonly object instance; - readonly Component prefab; + readonly Func prefabFinder; readonly string gameObjectName; ComponentDestination destination; @@ -51,12 +51,12 @@ internal ComponentRegistrationBuilder(in Scene scene, Type implementationType) } internal ComponentRegistrationBuilder( - Component prefab, + Func prefabFinder, Type implementationType, Lifetime lifetime) : base(implementationType, lifetime) { - this.prefab = prefab; + this.prefabFinder = prefabFinder; } internal ComponentRegistrationBuilder( @@ -81,10 +81,10 @@ public override Registration Build() { provider = new FindComponentProvider(ImplementationType, Parameters, in scene, in destination); } - else if (prefab != null) + else if (prefabFinder != null) { - var injector = InjectorCache.GetOrBuild(prefab.GetType()); - provider = new PrefabComponentProvider(prefab, injector, Parameters, in destination); + var injector = InjectorCache.GetOrBuild(ImplementationType); + provider = new PrefabComponentProvider(prefabFinder, injector, Parameters, in destination); } else { @@ -101,6 +101,12 @@ public ComponentRegistrationBuilder UnderTransform(Transform parent) } public ComponentRegistrationBuilder UnderTransform(Func parentFinder) + { + destination.ParentFinder = _ => parentFinder(); + return this; + } + + public ComponentRegistrationBuilder UnderTransform(Func parentFinder) { destination.ParentFinder = parentFinder; return this; diff --git a/VContainer/Assets/VContainer/Runtime/Unity/ContainerBuilderUnityExtensions.cs b/VContainer/Assets/VContainer/Runtime/Unity/ContainerBuilderUnityExtensions.cs index 6250ac5f..b6c9ae1d 100644 --- a/VContainer/Assets/VContainer/Runtime/Unity/ContainerBuilderUnityExtensions.cs +++ b/VContainer/Assets/VContainer/Runtime/Unity/ContainerBuilderUnityExtensions.cs @@ -168,14 +168,15 @@ public static ComponentRegistrationBuilder RegisterComponentOnNewGameObject( return builder.RegisterComponentOnNewGameObject(typeof(T), lifetime, newGameObjectName); } - public static ComponentRegistrationBuilder RegisterComponentInNewPrefab( + public static ComponentRegistrationBuilder RegisterComponentInNewPrefab( this IContainerBuilder builder, - Type type, - T prefab, + Type interfaceType, + Component prefab, Lifetime lifetime) - where T : Component { - return builder.Register(new ComponentRegistrationBuilder(prefab, type, lifetime)); + var componentRegistrationBuilder = builder.Register(new ComponentRegistrationBuilder(_ => prefab, prefab.GetType(), lifetime)); + componentRegistrationBuilder.As(interfaceType); + return componentRegistrationBuilder; } public static ComponentRegistrationBuilder RegisterComponentInNewPrefab( @@ -186,6 +187,26 @@ public static ComponentRegistrationBuilder RegisterComponentInNewPrefab( { return builder.RegisterComponentInNewPrefab(typeof(T), prefab, lifetime); } + + public static ComponentRegistrationBuilder RegisterComponentInNewPrefab( + this IContainerBuilder builder, + Func prefab, + Lifetime lifetime) + where T : Component + { + return builder.Register(new ComponentRegistrationBuilder(prefab, typeof(T), lifetime)); + } + + public static ComponentRegistrationBuilder RegisterComponentInNewPrefab( + this IContainerBuilder builder, + Func prefab, + Lifetime lifetime) + where TImplement : Component, TInterface + { + var componentRegistrationBuilder = builder.Register(new ComponentRegistrationBuilder(prefab, typeof(TImplement), lifetime)); + componentRegistrationBuilder.As(); + return componentRegistrationBuilder; + } #if VCONTAINER_ECS_INTEGRATION public readonly struct NewWorldBuilder diff --git a/VContainer/Assets/VContainer/Runtime/Unity/InstanceProviders/FindComponentProvider.cs b/VContainer/Assets/VContainer/Runtime/Unity/InstanceProviders/FindComponentProvider.cs index d6865d87..512044d7 100644 --- a/VContainer/Assets/VContainer/Runtime/Unity/InstanceProviders/FindComponentProvider.cs +++ b/VContainer/Assets/VContainer/Runtime/Unity/InstanceProviders/FindComponentProvider.cs @@ -29,7 +29,7 @@ public object SpawnInstance(IObjectResolver resolver) { var component = default(Component); - var parent = destination.GetParent(); + var parent = destination.GetParent(resolver); if (parent != null) { component = parent.GetComponentInChildren(componentType, true); diff --git a/VContainer/Assets/VContainer/Runtime/Unity/InstanceProviders/NewGameObjectProvider.cs b/VContainer/Assets/VContainer/Runtime/Unity/InstanceProviders/NewGameObjectProvider.cs index ea61314b..96ca364c 100644 --- a/VContainer/Assets/VContainer/Runtime/Unity/InstanceProviders/NewGameObjectProvider.cs +++ b/VContainer/Assets/VContainer/Runtime/Unity/InstanceProviders/NewGameObjectProvider.cs @@ -34,7 +34,7 @@ public object SpawnInstance(IObjectResolver resolver) var gameObject = new GameObject(name); gameObject.SetActive(false); - var parent = destination.GetParent(); + var parent = destination.GetParent(resolver); if (parent != null) { gameObject.transform.SetParent(parent); diff --git a/VContainer/Assets/VContainer/Runtime/Unity/InstanceProviders/PrefabComponentProvider.cs b/VContainer/Assets/VContainer/Runtime/Unity/InstanceProviders/PrefabComponentProvider.cs index e5887784..82beb168 100644 --- a/VContainer/Assets/VContainer/Runtime/Unity/InstanceProviders/PrefabComponentProvider.cs +++ b/VContainer/Assets/VContainer/Runtime/Unity/InstanceProviders/PrefabComponentProvider.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using UnityEngine; @@ -7,30 +8,32 @@ sealed class PrefabComponentProvider : IInstanceProvider { readonly IInjector injector; readonly IReadOnlyList customParameters; - readonly Component prefab; + readonly Func prefabFinder; ComponentDestination destination; public PrefabComponentProvider( - Component prefab, + Func prefabFinder, IInjector injector, IReadOnlyList customParameters, in ComponentDestination destination) { this.injector = injector; this.customParameters = customParameters; - this.prefab = prefab; + this.prefabFinder = prefabFinder; this.destination = destination; } public object SpawnInstance(IObjectResolver resolver) { + var prefab = prefabFinder(resolver); + var parent = destination.GetParent(resolver); + var wasActive = prefab.gameObject.activeSelf; if (wasActive) { prefab.gameObject.SetActive(false); } - - var parent = destination.GetParent(); + var component = parent != null ? UnityEngine.Object.Instantiate(prefab, parent) : UnityEngine.Object.Instantiate(prefab);