// MIT License - Copyright (c) 2025 wallstop // Full license text: https://github.com/wallstop/unity-helpers/blob/main/LICENSE #if REFLEX_PRESENT namespace WallstopStudios.UnityHelpers.Integrations.Reflex { using System; using System.Collections.Generic; using global::Reflex.Core; using global::Reflex.Injectors; using UnityEngine; using WallstopStudios.UnityHelpers.Core.Attributes; using WallstopStudios.UnityHelpers.Utils; /// /// Extension methods that bridge Reflex containers with relational component assignment. /// public static class ContainerRelationalExtensions { /// /// Injects a component using Reflex and assigns its relational fields. /// /// Component type. /// Reflex container. /// Component instance to inject and hydrate. /// The injected component instance. public static T InjectWithRelations(this Container container, T component) where T : Component { if (component == null) { return null; } if (container != null) { AttributeInjector.Inject(component, container); } container.AssignRelationalComponents(component); return component; } /// /// Assigns relational component fields on the supplied component. /// /// Reflex container. /// Component to hydrate. public static void AssignRelationalComponents(this Container container, Component component) { if (component == null) { return; } IRelationalComponentAssigner assigner = ResolveAssigner(container); if (assigner != null) { assigner.Assign(component); return; } component.AssignRelationalComponents(); } /// /// Assigns relational component fields across a GameObject hierarchy. /// /// Reflex container. /// Hierarchy root. /// /// When true, includes inactive children during assignment. /// public static void AssignRelationalHierarchy( this Container container, GameObject root, bool includeInactiveChildren = true ) { if (root == null) { return; } IRelationalComponentAssigner assigner = ResolveAssigner(container); if (assigner != null) { assigner.AssignHierarchy(root, includeInactiveChildren); return; } using PooledResource> pooledComponents = Buffers.List.Get( out List components ); root.GetComponentsInChildren(includeInactiveChildren, components); for (int i = 0; i < components.Count; i++) { Component component = components[i]; if (component == null) { continue; } component.AssignRelationalComponents(); } } /// /// Instantiates a component prefab, injects it, and assigns relational fields. /// /// Component type contained by the prefab. /// Reflex container. /// Component prefab. /// Optional parent transform. /// The instantiated and hydrated component. public static T InstantiateComponentWithRelations( this Container container, T prefab, Transform parent = null ) where T : Component { if (prefab == null) { throw new ArgumentNullException(nameof(prefab)); } T instance = UnityEngine.Object.Instantiate(prefab, parent); return container.InjectWithRelations(instance); } /// /// Instantiates a GameObject prefab, injects the hierarchy, and assigns relational fields. /// /// Reflex container. /// GameObject prefab. /// Optional parent transform. /// /// When true, includes inactive children during relational assignment. /// /// The instantiated GameObject. public static GameObject InstantiateGameObjectWithRelations( this Container container, GameObject prefab, Transform parent = null, bool includeInactiveChildren = true ) { if (prefab == null) { throw new ArgumentNullException(nameof(prefab)); } GameObject instance = UnityEngine.Object.Instantiate(prefab, parent); container.InjectGameObjectWithRelations(instance, includeInactiveChildren); return instance; } /// /// Injects all components in a hierarchy and assigns relational fields. /// /// Reflex container. /// Root GameObject. /// /// When true, includes inactive children during relational assignment. /// public static void InjectGameObjectWithRelations( this Container container, GameObject root, bool includeInactiveChildren = true ) { if (root == null) { return; } if (container != null) { GameObjectInjector.InjectRecursive(root, container); } container.AssignRelationalHierarchy(root, includeInactiveChildren); } private static IRelationalComponentAssigner ResolveAssigner(Container container) { if (container == null) { return null; } if (container.HasBinding()) { return container.Resolve(); } return null; } } } #endif