From 4e409490ac25f4da6edc0f64ea38ef800e36b3a7 Mon Sep 17 00:00:00 2001 From: Vladislav Kantaev Date: Thu, 11 Nov 2021 21:44:03 +0300 Subject: [PATCH 1/3] Add container builder extensions: RegisterIfNotNull and TryResolveAndRegister() [closes #65] --- .../Runtime/ContainerBuilderExtensions.cs | 49 ++++++ .../ContainerBuilderExtensions.cs.meta | 3 + .../ContainerBuilderExtensionsTests.cs | 139 ++++++++++++++++++ .../ContainerBuilderExtensionsTests.cs.meta | 3 + 4 files changed, 194 insertions(+) create mode 100644 Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/ContainerBuilderExtensions.cs create mode 100644 Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/ContainerBuilderExtensions.cs.meta create mode 100644 Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Tests/Runtime/ContainerBuilderExtensionsTests.cs create mode 100644 Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Tests/Runtime/ContainerBuilderExtensionsTests.cs.meta diff --git a/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/ContainerBuilderExtensions.cs b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/ContainerBuilderExtensions.cs new file mode 100644 index 00000000..63dab51e --- /dev/null +++ b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/ContainerBuilderExtensions.cs @@ -0,0 +1,49 @@ +using System; +using JetBrains.Annotations; +using UnityEngine.Assertions; +using Object = UnityEngine.Object; + +namespace DELTation.DIFramework +{ + /// + /// Utility methods for registering dependencies in ContainerBuilders. + /// + public static class ContainerBuilderExtensions + { + /// + /// Register the given dependency only if it is not null (it checks for Unity null too). + /// + /// Container builder to register dependency in. + /// Registered object. + /// The same container builder. + /// If is null. + [NotNull] + public static ContainerBuilder RegisterIfNotNull([NotNull] this ContainerBuilder containerBuilder, + [CanBeNull] object obj) + { + if (containerBuilder == null) throw new ArgumentNullException(nameof(containerBuilder)); + if (IsNullOrUnityNull(obj)) return containerBuilder; + + Assert.IsNotNull(obj); + return containerBuilder.Register(obj); + } + + private static bool IsNullOrUnityNull([CanBeNull] object obj) => + obj is Object unityObj ? unityObj == null : obj == null; + + /// + /// Try to resolve a dependency globally. If resolved, register it. + /// + /// Container builder to register dependency in. + /// Type of dependency to try to resolve. + /// The same container builder. + /// If is null. + [NotNull] + public static ContainerBuilder TryResolveGloballyAndRegister( + [NotNull] this ContainerBuilder containerBuilder) where T : class + { + if (containerBuilder == null) throw new ArgumentNullException(nameof(containerBuilder)); + return Di.TryResolveGlobally(out T service) ? containerBuilder.Register(service) : containerBuilder; + } + } +} \ No newline at end of file diff --git a/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/ContainerBuilderExtensions.cs.meta b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/ContainerBuilderExtensions.cs.meta new file mode 100644 index 00000000..1b24e706 --- /dev/null +++ b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/ContainerBuilderExtensions.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 0abe5b5f35ce44aeb0108416113748cb +timeCreated: 1636654604 \ No newline at end of file diff --git a/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Tests/Runtime/ContainerBuilderExtensionsTests.cs b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Tests/Runtime/ContainerBuilderExtensionsTests.cs new file mode 100644 index 00000000..79604347 --- /dev/null +++ b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Tests/Runtime/ContainerBuilderExtensionsTests.cs @@ -0,0 +1,139 @@ +using DELTation.DIFramework.Containers; +using NUnit.Framework; +using UnityEngine; + +namespace DELTation.DIFramework.Tests.Runtime +{ + public class ContainerBuilderExtensionsTests : TestFixtureBase + { + [Test] + public void GivenRegisterIfNotNull_WhenNull_ThenNoExceptions() + { + // Arrange + CreateContainerWith(); + + // Act + var resolved = Di.TryResolveGlobally(out _); + + // Assert + Assert.IsFalse(resolved); + } + + [Test] + public void GivenRegisterIfNotNull_WhenUnityNull_ThenNoExceptions() + { + // Arrange + CreateContainerWith(); + + // Act + var resolved = Di.TryResolveGlobally(out _); + + // Assert + Assert.IsFalse(resolved); + } + + [Test] + public void GivenRegisterIfNotNull_WhenNotNull_ThenRegistered() + { + // Arrange + CreateContainerWith(); + + // Act + var resolved = Di.TryResolveGlobally(out _); + + // Assert + Assert.IsTrue(resolved); + } + + [Test] + public void GivenRegisterIfNotNull_WhenNotNullUnityObj_ThenRegistered() + { + // Arrange + CreateContainerWith(); + + // Act + var resolved = Di.TryResolveGlobally(out _); + + // Assert + Assert.IsTrue(resolved); + } + + [Test] + public void GivenTryResolveGloballyAndRegister_WhenResolved_ThenRegistered() + { + // Arrange + CreateContainerWith(); + CreateContainerWith(); + + // Act + var resolved = Di.TryResolveGlobally(out _); + + // Assert + Assert.IsTrue(resolved); + } + + [Test] + public void GivenTryResolveGloballyAndRegister_WhenNotResolved_ThenNotRegistered() + { + // Arrange + CreateContainerWith(); + + // Act + var resolved = Di.TryResolveGlobally(out _); + + // Assert + Assert.IsFalse(resolved); + } + + private class ContainerRegisteringNull : DependencyContainerBase + { + protected override void ComposeDependencies(ContainerBuilder builder) + { + builder.RegisterIfNotNull(null); + } + } + + private class ContainerRegisteringUnityNull : DependencyContainerBase + { + protected override void ComposeDependencies(ContainerBuilder builder) + { + var c = gameObject.AddComponent(); + DestroyImmediate(c); // using immediate so that object is null right away + builder.RegisterIfNotNull(c); + } + } + + private class ContainerRegisteringNotNull : DependencyContainerBase + { + protected override void ComposeDependencies(ContainerBuilder builder) + { + builder.RegisterIfNotNull(new object()); + } + } + + private class ContainerRegisteringNotNullUnityObj : DependencyContainerBase + { + protected override void ComposeDependencies(ContainerBuilder builder) + { + var c = gameObject.AddComponent(); + builder.RegisterIfNotNull(c); + } + } + + private class ContainerResolvingAndRegisteringString : DependencyContainerBase + { + protected override void ComposeDependencies(ContainerBuilder builder) + { + builder.TryResolveGloballyAndRegister(); + } + } + + private class ContainerRegisteringString : DependencyContainerBase + { + protected override void ComposeDependencies(ContainerBuilder builder) + { + builder.Register("Some string"); + } + } + } +} \ No newline at end of file diff --git a/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Tests/Runtime/ContainerBuilderExtensionsTests.cs.meta b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Tests/Runtime/ContainerBuilderExtensionsTests.cs.meta new file mode 100644 index 00000000..36eefa6a --- /dev/null +++ b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Tests/Runtime/ContainerBuilderExtensionsTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1dfb366ccede4ec8a8f61a0730ec9c1d +timeCreated: 1636655570 \ No newline at end of file From 80509fdc4f2c0a376b12ec2abaabbf81b339b34b Mon Sep 17 00:00:00 2001 From: Vladislav Kantaev Date: Thu, 11 Nov 2021 23:21:56 +0300 Subject: [PATCH 2/3] Add IStartable, IUpdatable, and IDestroyable [closes #66] --- DIFramework.Lifecycle.csproj.DotSettings | 3 + .../DIFramework/Runtime/ContainerLifecycle.cs | 101 ++++++++++++ .../Runtime/ContainerLifecycle.cs.meta | 3 + .../DIFramework/Runtime/DIFramework.asmdef | 4 +- .../DIFramework/Runtime/Lifecycle.meta | 8 + .../Lifecycle/DIFramework.Lifecycle.asmdef | 13 ++ .../DIFramework.Lifecycle.asmdef.meta | 7 + .../Runtime/Lifecycle/IDestroyable.cs | 12 ++ .../Runtime/Lifecycle/IDestroyable.cs.meta | 3 + .../Runtime/Lifecycle/IStartable.cs | 12 ++ .../Runtime/Lifecycle/IStartable.cs.meta | 3 + .../Runtime/Lifecycle/IUpdatable.cs | 12 ++ .../Runtime/Lifecycle/IUpdatable.cs.meta | 3 + .../Tests/Runtime/ContainerLifecycleTests.cs | 149 ++++++++++++++++++ .../Runtime/ContainerLifecycleTests.cs.meta | 3 + .../Tests/Runtime/DIFramework.Tests.asmdef | 3 +- di-framework.sln.DotSettings | 6 +- 17 files changed, 342 insertions(+), 3 deletions(-) create mode 100644 DIFramework.Lifecycle.csproj.DotSettings create mode 100644 Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/ContainerLifecycle.cs create mode 100644 Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/ContainerLifecycle.cs.meta create mode 100644 Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/Lifecycle.meta create mode 100644 Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/Lifecycle/DIFramework.Lifecycle.asmdef create mode 100644 Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/Lifecycle/DIFramework.Lifecycle.asmdef.meta create mode 100644 Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/Lifecycle/IDestroyable.cs create mode 100644 Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/Lifecycle/IDestroyable.cs.meta create mode 100644 Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/Lifecycle/IStartable.cs create mode 100644 Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/Lifecycle/IStartable.cs.meta create mode 100644 Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/Lifecycle/IUpdatable.cs create mode 100644 Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/Lifecycle/IUpdatable.cs.meta create mode 100644 Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Tests/Runtime/ContainerLifecycleTests.cs create mode 100644 Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Tests/Runtime/ContainerLifecycleTests.cs.meta diff --git a/DIFramework.Lifecycle.csproj.DotSettings b/DIFramework.Lifecycle.csproj.DotSettings new file mode 100644 index 00000000..a30be5a7 --- /dev/null +++ b/DIFramework.Lifecycle.csproj.DotSettings @@ -0,0 +1,3 @@ + + True + True \ No newline at end of file diff --git a/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/ContainerLifecycle.cs b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/ContainerLifecycle.cs new file mode 100644 index 00000000..364b536e --- /dev/null +++ b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/ContainerLifecycle.cs @@ -0,0 +1,101 @@ +using System; +using System.Collections.Generic; +using DELTation.DIFramework.Containers; +using DELTation.DIFramework.Lifecycle; +using UnityEngine; +using UnityEngine.Assertions; + +namespace DELTation.DIFramework +{ + /// + /// Pulls all registered objects from a container and calls lifecycle events on them + /// (, , + /// ). + /// + // ReSharper disable once ClassWithVirtualMembersNeverInherited.Global + public class ContainerLifecycle : MonoBehaviour + { + [SerializeField] private DependencyContainerBase _container; + + private readonly List _destroyables = new List(); + private readonly List _startables = new List(); + private readonly List _updatables = new List(); + + public DependencyContainerBase Container + { + get => _container; + set + { + if (value == null) throw new ArgumentNullException(nameof(value), "Container cannot be null."); + _container = value; + } + } + + protected virtual void Start() + { + AssetThatContainerIsAssigned(); + PullObjectsFromContainer(); + InvokeStartables(); + } + + protected virtual void Update() + { + InvokeUpdatables(); + } + + protected virtual void OnDestroy() + { + InvokeDestroyables(); + } + + private void AssetThatContainerIsAssigned() + { + Assert.IsNotNull(_container, $"Container has to be assigned ({gameObject.name})."); + } + + private void InvokeStartables() + { + // ReSharper disable once ForCanBeConvertedToForeach + for (var index = 0; index < _startables.Count; index++) + { + _startables[index].OnStart(); + } + } + + private void InvokeUpdatables() + { + // ReSharper disable once ForCanBeConvertedToForeach + for (var index = 0; index < _updatables.Count; index++) + { + _updatables[index].OnUpdate(); + } + } + + private void InvokeDestroyables() + { + // ReSharper disable once ForCanBeConvertedToForeach + for (var index = 0; index < _destroyables.Count; index++) + { + _destroyables[index].OnDestroy(); + } + } + + private void PullObjectsFromContainer() + { + var allObjects = new List(); + _container.GetAllRegisteredObjects(allObjects); + + for (var index = 0; index < allObjects.Count; index++) + { + var obj = allObjects[index]; + // ReSharper disable once ConvertIfStatementToSwitchStatement + if (obj is IStartable startable) + _startables.Add(startable); + if (obj is IUpdatable updatable) + _updatables.Add(updatable); + if (obj is IDestroyable destroyable) + _destroyables.Add(destroyable); + } + } + } +} \ No newline at end of file diff --git a/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/ContainerLifecycle.cs.meta b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/ContainerLifecycle.cs.meta new file mode 100644 index 00000000..6e91a663 --- /dev/null +++ b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/ContainerLifecycle.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c4573e2ad52a42b1b16440bc9fe52267 +timeCreated: 1636659639 \ No newline at end of file diff --git a/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/DIFramework.asmdef b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/DIFramework.asmdef index c5c1bfc5..b59544eb 100644 --- a/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/DIFramework.asmdef +++ b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/DIFramework.asmdef @@ -1,6 +1,8 @@ { "name": "DIFramework", - "references": [], + "references": [ + "GUID:7661adf0dcc98034093743fe3a566d1a" + ], "includePlatforms": [], "excludePlatforms": [], "allowUnsafeCode": false, diff --git a/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/Lifecycle.meta b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/Lifecycle.meta new file mode 100644 index 00000000..69aeb85d --- /dev/null +++ b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/Lifecycle.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5183f2316243f2b47ab78fca0e2e95d6 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/Lifecycle/DIFramework.Lifecycle.asmdef b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/Lifecycle/DIFramework.Lifecycle.asmdef new file mode 100644 index 00000000..0c10f576 --- /dev/null +++ b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/Lifecycle/DIFramework.Lifecycle.asmdef @@ -0,0 +1,13 @@ +{ + "name": "DIFramework.Lifecycle", + "references": [], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/Lifecycle/DIFramework.Lifecycle.asmdef.meta b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/Lifecycle/DIFramework.Lifecycle.asmdef.meta new file mode 100644 index 00000000..314d569c --- /dev/null +++ b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/Lifecycle/DIFramework.Lifecycle.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 7661adf0dcc98034093743fe3a566d1a +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/Lifecycle/IDestroyable.cs b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/Lifecycle/IDestroyable.cs new file mode 100644 index 00000000..7b90dd0d --- /dev/null +++ b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/Lifecycle/IDestroyable.cs @@ -0,0 +1,12 @@ +namespace DELTation.DIFramework.Lifecycle +{ + public interface IDestroyable + { + /// + /// Executed by + /// + /// at Unity's OnDestroy callback. + /// + void OnDestroy(); + } +} \ No newline at end of file diff --git a/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/Lifecycle/IDestroyable.cs.meta b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/Lifecycle/IDestroyable.cs.meta new file mode 100644 index 00000000..01931a14 --- /dev/null +++ b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/Lifecycle/IDestroyable.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d661bcdde53f404499842f0947458444 +timeCreated: 1636659604 \ No newline at end of file diff --git a/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/Lifecycle/IStartable.cs b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/Lifecycle/IStartable.cs new file mode 100644 index 00000000..84fae059 --- /dev/null +++ b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/Lifecycle/IStartable.cs @@ -0,0 +1,12 @@ +namespace DELTation.DIFramework.Lifecycle +{ + public interface IStartable + { + /// + /// Executed by + /// + /// at Unity's Start callback. + /// + void OnStart(); + } +} \ No newline at end of file diff --git a/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/Lifecycle/IStartable.cs.meta b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/Lifecycle/IStartable.cs.meta new file mode 100644 index 00000000..5f48c9c7 --- /dev/null +++ b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/Lifecycle/IStartable.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 7a951d3e33d34aeeaadc32922fbd5383 +timeCreated: 1636659411 \ No newline at end of file diff --git a/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/Lifecycle/IUpdatable.cs b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/Lifecycle/IUpdatable.cs new file mode 100644 index 00000000..a2059ba8 --- /dev/null +++ b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/Lifecycle/IUpdatable.cs @@ -0,0 +1,12 @@ +namespace DELTation.DIFramework.Lifecycle +{ + public interface IUpdatable + { + /// + /// Executed by + /// + /// at Unity's Update callback. + /// + void OnUpdate(); + } +} \ No newline at end of file diff --git a/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/Lifecycle/IUpdatable.cs.meta b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/Lifecycle/IUpdatable.cs.meta new file mode 100644 index 00000000..fb2e6b5c --- /dev/null +++ b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Runtime/Lifecycle/IUpdatable.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 8e31b6dbf8ba4cf19d095c6c9a1f8b58 +timeCreated: 1636659489 \ No newline at end of file diff --git a/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Tests/Runtime/ContainerLifecycleTests.cs b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Tests/Runtime/ContainerLifecycleTests.cs new file mode 100644 index 00000000..c5de3575 --- /dev/null +++ b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Tests/Runtime/ContainerLifecycleTests.cs @@ -0,0 +1,149 @@ +using System.Collections; +using System.Collections.Generic; +using DELTation.DIFramework.Containers; +using DELTation.DIFramework.Lifecycle; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; + +namespace DELTation.DIFramework.Tests.Runtime +{ + public class ContainerLifecycleTests : TestFixtureBase + { + private DependencyContainer _container; + private Destroyable _destroyable; + private Startable _startable; + private Updatable _updatable; + + [SetUp] + public void SetUp() + { + _startable = new Startable(); + _updatable = new Updatable(); + _destroyable = new Destroyable(); + + _container = CreateContainerWith(); + } + + private void InitLifecycle() + { + var lifecycle = _container.gameObject.AddComponent(); + lifecycle.Container = _container; + } + + [UnityTest] + public IEnumerator GivenContainerWithLifecycle_WhenEmpty_ThenNoCalls() + { + // Arrange + InitLifecycle(); + + // Act + yield return null; + + // Assert + AssertThatCallsCountsAreEqual(0, 0, 0); + } + + [UnityTest] + public IEnumerator GivenContainerWithLifecycle_WhenStarted_ThenStartIsCalled() + { + // Arrange + AddAllObjects(); + InitLifecycle(); + + // Act + yield return null; + + // Assert + AssertThatCallsCountsAreEqual(1, 1, 0); + } + + [UnityTest] + public IEnumerator GivenContainerWithLifecycle_WhenStartedAndExecutedSeveralFrames_ThenStartIsCalled() + { + // Arrange + AddAllObjects(); + InitLifecycle(); + + // Act + yield return null; + yield return null; + + // Assert + AssertThatCallsCountsAreEqual(1, 2, 0); + } + + [UnityTest] + public IEnumerator GivenContainerWithLifecycle_WhenDestroyed_ThenStartIsCalled() + { + // Arrange + AddAllObjects(); + InitLifecycle(); + + // Act + yield return null; + Object.Destroy(_container.GetComponent()); + yield return null; + + // Assert + AssertThatCallsCountsAreEqual(1, 1, 1); + } + + private void AddAllObjects() + { + _container.ObjectsToRegister.Add(_startable); + _container.ObjectsToRegister.Add(_updatable); + _container.ObjectsToRegister.Add(_destroyable); + } + + private void AssertThatCallsCountsAreEqual(int startableCalls, int updatableCalls, int destroyableCalls) + { + Assert.AreEqual(startableCalls, _startable.CallsCount); + Assert.AreEqual(updatableCalls, _updatable.CallsCount); + Assert.AreEqual(destroyableCalls, _destroyable.CallsCount); + } + + private class Startable : IStartable + { + public int CallsCount { get; private set; } + + public void OnStart() + { + CallsCount++; + } + } + + private class Updatable : IUpdatable + { + public int CallsCount { get; private set; } + + public void OnUpdate() + { + CallsCount++; + } + } + + private class Destroyable : IDestroyable + { + public int CallsCount { get; private set; } + + public void OnDestroy() + { + CallsCount++; + } + } + + private class DependencyContainer : DependencyContainerBase + { + public List ObjectsToRegister { get; } = new List(); + + protected override void ComposeDependencies(ContainerBuilder builder) + { + foreach (var o in ObjectsToRegister) + { + builder.Register(o); + } + } + } + } +} \ No newline at end of file diff --git a/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Tests/Runtime/ContainerLifecycleTests.cs.meta b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Tests/Runtime/ContainerLifecycleTests.cs.meta new file mode 100644 index 00000000..f525af48 --- /dev/null +++ b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Tests/Runtime/ContainerLifecycleTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 7f64ce98afcc4cec9c3dc34125113553 +timeCreated: 1636660305 \ No newline at end of file diff --git a/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Tests/Runtime/DIFramework.Tests.asmdef b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Tests/Runtime/DIFramework.Tests.asmdef index 755eab52..455222b9 100644 --- a/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Tests/Runtime/DIFramework.Tests.asmdef +++ b/Packages/com.deltation.di-framework/Assets/DELTation/DIFramework/Tests/Runtime/DIFramework.Tests.asmdef @@ -3,7 +3,8 @@ "references": [ "GUID:1b60fcce313931d4f9eefc7f1c079778", "GUID:27619889b8ba8c24980f49ee34dbb44a", - "GUID:91836b14885b8a34196f4aa8303d7793" + "GUID:91836b14885b8a34196f4aa8303d7793", + "GUID:7661adf0dcc98034093743fe3a566d1a" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/di-framework.sln.DotSettings b/di-framework.sln.DotSettings index a6d5c34a..5936e9f9 100644 --- a/di-framework.sln.DotSettings +++ b/di-framework.sln.DotSettings @@ -1,3 +1,7 @@  + True True - True \ No newline at end of file + True + True + True + True \ No newline at end of file From 8dc8c27f0a3fe2544a97d60f6594986afc2f1449 Mon Sep 17 00:00:00 2001 From: Vladislav Kantaev Date: Thu, 11 Nov 2021 23:22:11 +0300 Subject: [PATCH 3/3] Bump package version --- Packages/com.deltation.di-framework/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Packages/com.deltation.di-framework/package.json b/Packages/com.deltation.di-framework/package.json index 190f0e91..606e8eba 100644 --- a/Packages/com.deltation.di-framework/package.json +++ b/Packages/com.deltation.di-framework/package.json @@ -1,6 +1,6 @@ { "name": "com.deltation.di-framework", - "version": "2.5.2", + "version": "2.5.3", "displayName": "DI Framework", "description": "A simple Unity DI/IoC framework to inject dependencies into your components.", "unity": "2019.4",