diff --git a/Assets/Reflex.EditModeTests/OnInjectedListenerTests.cs b/Assets/Reflex.EditModeTests/OnInjectedListenerTests.cs new file mode 100644 index 00000000..c3f0a4d7 --- /dev/null +++ b/Assets/Reflex.EditModeTests/OnInjectedListenerTests.cs @@ -0,0 +1,96 @@ +using System; +using System.Collections.Generic; +using FluentAssertions; +using NUnit.Framework; +using Reflex.Attributes; +using Reflex.Core; +using Reflex.Enums; + +namespace Reflex.EditModeTests +{ + public class OnInjectedListenerTests + { + private static class StaticEventBus + { + public static event Action OnInjectedEvent; + public static void RaiseOnInjectedEvent(char id) => OnInjectedEvent?.Invoke(id); + } + + private abstract class AttributeInjected : IOnInjectedListener + { + private readonly char _id; + protected AttributeInjected(char id) => _id = id; + public void OnInjected() => StaticEventBus.RaiseOnInjectedEvent(_id); + } + + private class AttributeInjectedA : AttributeInjected + { + [Inject] private readonly AttributeInjectedB _b; + public AttributeInjectedA() : base('a') { } + } + + private class AttributeInjectedB : AttributeInjected + { + [Inject] private readonly AttributeInjectedC _c; + public AttributeInjectedB() : base('b') { } + } + + private class AttributeInjectedC : AttributeInjected + { + public AttributeInjectedC() : base('c') { } + } + + private class ConstructorInjectedA : AttributeInjected + { + private readonly ConstructorInjectedB _b; + public ConstructorInjectedA(ConstructorInjectedB b) : base('a') => _b = b; + } + + private class ConstructorInjectedB : AttributeInjected + { + private readonly ConstructorInjectedC _c; + public ConstructorInjectedB(ConstructorInjectedC c) : base('b') => _c = c; + } + + private class ConstructorInjectedC : AttributeInjected + { + public ConstructorInjectedC() : base('c') { } + } + + [Test] + public void AttributeInjectedObjects_GetsOnInjectedRaisedRecursively() + { + var constructionOrder = new List(3); + StaticEventBus.OnInjectedEvent -= UpdateOnInjectedOrder; + StaticEventBus.OnInjectedEvent += UpdateOnInjectedOrder; + void UpdateOnInjectedOrder(char service) => constructionOrder.Add(service); + + var container = new ContainerBuilder() + .RegisterType(typeof(AttributeInjectedA), Lifetime.Singleton, Resolution.Lazy) + .RegisterType(typeof(AttributeInjectedB), Lifetime.Singleton, Resolution.Lazy) + .RegisterType(typeof(AttributeInjectedC), Lifetime.Singleton, Resolution.Lazy) + .Build(); + + container.Resolve(); + string.Join(string.Empty, constructionOrder).Should().BeEquivalentTo("cba"); + } + + [Test] + public void ConstructorInjectedObjects_GetsOnInjectedRaisedRecursively() + { + var constructionOrder = new List(3); + StaticEventBus.OnInjectedEvent -= UpdateOnInjectedOrder; + StaticEventBus.OnInjectedEvent += UpdateOnInjectedOrder; + void UpdateOnInjectedOrder(char service) => constructionOrder.Add(service); + + var container = new ContainerBuilder() + .RegisterType(typeof(ConstructorInjectedA), Lifetime.Singleton, Resolution.Lazy) + .RegisterType(typeof(ConstructorInjectedB), Lifetime.Singleton, Resolution.Lazy) + .RegisterType(typeof(ConstructorInjectedC), Lifetime.Singleton, Resolution.Lazy) + .Build(); + + container.Resolve(); + string.Join(string.Empty, constructionOrder).Should().BeEquivalentTo("cba"); + } + } +} \ No newline at end of file diff --git a/Assets/Reflex.EditModeTests/OnInjectedListenerTests.cs.meta b/Assets/Reflex.EditModeTests/OnInjectedListenerTests.cs.meta new file mode 100644 index 00000000..b07e7459 --- /dev/null +++ b/Assets/Reflex.EditModeTests/OnInjectedListenerTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: fb2a72c89ec145f2bbdb6858945c09b3 +timeCreated: 1773175698 \ No newline at end of file diff --git a/Assets/Reflex/Core/Container.cs b/Assets/Reflex/Core/Container.cs index 1d94c41c..c61b907d 100644 --- a/Assets/Reflex/Core/Container.cs +++ b/Assets/Reflex/Core/Container.cs @@ -79,7 +79,13 @@ public T Construct() public object Construct(Type concrete) { var instance = ConstructorInjector.Construct(concrete, this); - AttributeInjector.Inject(instance, this); + AttributeInjector.Inject(instance, this); + + if (instance is IOnInjectedListener onInjectedListener) + { + onInjectedListener.OnInjected(); + } + return instance; } diff --git a/Assets/Reflex/Core/IOnInjectedListener.cs b/Assets/Reflex/Core/IOnInjectedListener.cs new file mode 100644 index 00000000..042943b2 --- /dev/null +++ b/Assets/Reflex/Core/IOnInjectedListener.cs @@ -0,0 +1,7 @@ +namespace Reflex.Core +{ + public interface IOnInjectedListener + { + void OnInjected(); + } +} \ No newline at end of file diff --git a/Assets/Reflex/Core/IOnInjectedListener.cs.meta b/Assets/Reflex/Core/IOnInjectedListener.cs.meta new file mode 100644 index 00000000..57c94fe7 --- /dev/null +++ b/Assets/Reflex/Core/IOnInjectedListener.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: e152e146a85148a4b9eb2a6e33944931 +timeCreated: 1773188652 \ No newline at end of file