public ConditionCopyNonLazyBinder OnInstantiated <T>( Action <InjectContext, T> callback) { // Can't do this here because of factory bindings //Assert.That(BindInfo.ContractTypes.All(x => x.DerivesFromOrEqual<T>())); BindInfo.InstantiatedCallback = (ctx, obj) => { if (obj is ValidationMarker) { Assert.That(ctx.Container.IsValidating); ValidationMarker marker = obj as ValidationMarker; Assert.That(marker.MarkedType.DerivesFromOrEqual <T>(), "Invalid generic argument to OnInstantiated! {0} must be type {1}", marker.MarkedType, typeof(T)); } else { Assert.That(obj == null || obj is T, "Invalid generic argument to OnInstantiated! {0} must be type {1}", obj.GetType(), typeof(T)); callback(ctx, (T)obj); } }; return(this); }
public void GetAllInstancesWithInjectSplit( InjectContext context, List <TypeValuePair> args, out Action injectAction, List <object> buffer) { Assert.IsNotNull(context); Assert.That(context.ObjectType.DerivesFrom <Component>(), "Object '{0}' can only be injected into MonoBehaviour's since it was bound with 'FromNewComponentSibling'. Attempted to inject into non-MonoBehaviour '{1}'", context.MemberType, context.ObjectType); object instance; if (!_container.IsValidating || TypeAnalyzer.ShouldAllowDuringValidation(_componentType)) { var gameObj = ((Component)context.ObjectInstance).gameObject; var componentInstance = gameObj.GetComponent(_componentType); instance = componentInstance; // Use componentInstance so that it triggers unity's overloaded comparison operator // So if the component is there but missing then it returns null // (https://github.com/svermeulen/UniDi/issues/582) if (componentInstance != null) { injectAction = null; buffer.Add(instance); return; } instance = gameObj.AddComponent(_componentType); } else { instance = new ValidationMarker(_componentType); } // Note that we don't just use InstantiateComponentOnNewGameObjectExplicit here // because then circular references don't work injectAction = () => { var extraArgs = UniDiPools.SpawnList <TypeValuePair>(); extraArgs.AllocFreeAddRange(_extraArguments); extraArgs.AllocFreeAddRange(args); _container.InjectExplicit(instance, _componentType, extraArgs, context, _concreteIdentifier); Assert.That(extraArgs.IsEmpty()); UniDiPools.DespawnList(extraArgs); if (_instantiateCallback != null) { _instantiateCallback(context, instance); } }; buffer.Add(instance); }
public void GetAllInstancesWithInjectSplit( InjectContext context, List <TypeValuePair> args, out Action injectAction, List <object> buffer) { Assert.IsNotNull(context); object instance; // We still want to make sure we can get the game object during validation var gameObj = GetGameObject(context); var wasActive = gameObj.activeSelf; if (wasActive && ShouldToggleActive) { // We need to do this in some cases to ensure that [Inject] always gets // called before awake / start gameObj.SetActive(false); } if (!_container.IsValidating || TypeAnalyzer.ShouldAllowDuringValidation(_componentType)) { if (_componentType == typeof(Transform)) // Treat transform as a special case because it's the one component that's always automatically added // Otherwise, calling AddComponent below will fail and return null // This is nice to allow doing things like // Container.Bind<Transform>().FromNewComponentOnNewGameObject(); { instance = gameObj.transform; } else { instance = gameObj.AddComponent(_componentType); } Assert.IsNotNull(instance); } else { instance = new ValidationMarker(_componentType); } injectAction = () => { try { var extraArgs = UniDiPools.SpawnList <TypeValuePair>(); extraArgs.AllocFreeAddRange(_extraArguments); extraArgs.AllocFreeAddRange(args); _container.InjectExplicit(instance, _componentType, extraArgs, context, _concreteIdentifier); Assert.That(extraArgs.Count == 0); UniDiPools.DespawnList(extraArgs); if (_instantiateCallback != null) { _instantiateCallback(context, instance); } } finally { if (wasActive && ShouldToggleActive) { gameObj.SetActive(true); } } }; buffer.Add(instance); }