From 604f2cf790511c0df1af7fec617ec05bdf76c98a Mon Sep 17 00:00:00 2001 From: Frolov Date: Mon, 10 Jun 2024 15:00:19 +0700 Subject: [PATCH] local scope injection bugs fixed --- Assets/Scenes/SampleScene.unity | 49 ++++++++++++++++++- .../UniDI/Scripts/Resolvers/MethodResolver.cs | 27 +++++++++- .../Scripts/Strategies/ResolvingStrategy.cs | 15 ++++++ Assets/UniDI/Scripts/UniDIContext.cs | 4 ++ Assets/UniDI/package.json | 2 +- Assets/UniDITestScripts/LocalScopeTests.meta | 8 +++ .../LocalScopeTests/LocalConsumerClass.cs | 13 +++++ .../LocalConsumerClass.cs.meta | 2 + .../LocalScopeTests/LocalInjectedClass.cs | 12 +++++ .../LocalInjectedClass.cs.meta | 2 + .../LocalScopeTests/LocalScopeTester.cs | 23 +++++++++ .../LocalScopeTests/LocalScopeTester.cs.meta | 2 + .../PerformanceTestStarter.cs | 3 +- .../PerformanceTests/PerformanceTester.cs | 6 +-- 14 files changed, 157 insertions(+), 11 deletions(-) create mode 100644 Assets/UniDITestScripts/LocalScopeTests.meta create mode 100644 Assets/UniDITestScripts/LocalScopeTests/LocalConsumerClass.cs create mode 100644 Assets/UniDITestScripts/LocalScopeTests/LocalConsumerClass.cs.meta create mode 100644 Assets/UniDITestScripts/LocalScopeTests/LocalInjectedClass.cs create mode 100644 Assets/UniDITestScripts/LocalScopeTests/LocalInjectedClass.cs.meta create mode 100644 Assets/UniDITestScripts/LocalScopeTests/LocalScopeTester.cs create mode 100644 Assets/UniDITestScripts/LocalScopeTests/LocalScopeTester.cs.meta diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/SampleScene.unity index f5a6094..fd71524 100644 --- a/Assets/Scenes/SampleScene.unity +++ b/Assets/Scenes/SampleScene.unity @@ -130,12 +130,12 @@ GameObject: - component: {fileID: 357009554} - component: {fileID: 357009553} m_Layer: 0 - m_Name: ReleaseDependency + m_Name: ReleaseDependencyTest m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 1 + m_IsActive: 0 --- !u!114 &357009553 MonoBehaviour: m_ObjectHideFlags: 0 @@ -318,6 +318,50 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: b5d2362725654c94894df5bd0cc8a6d4, type: 3} m_Name: m_EditorClassIdentifier: +--- !u!1 &1794166374 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1794166376} + - component: {fileID: 1794166375} + m_Layer: 0 + m_Name: LocalScopeTest + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1794166375 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1794166374} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 3a99b13ce29beec4b870bb953e8df2ff, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!4 &1794166376 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1794166374} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &1890540586 GameObject: m_ObjectHideFlags: 0 @@ -372,3 +416,4 @@ SceneRoots: - {fileID: 1249362804} - {fileID: 1890540587} - {fileID: 357009554} + - {fileID: 1794166376} diff --git a/Assets/UniDI/Scripts/Resolvers/MethodResolver.cs b/Assets/UniDI/Scripts/Resolvers/MethodResolver.cs index ff1a02f..016bc7b 100644 --- a/Assets/UniDI/Scripts/Resolvers/MethodResolver.cs +++ b/Assets/UniDI/Scripts/Resolvers/MethodResolver.cs @@ -14,6 +14,7 @@ internal class MethodResolver private readonly ParameterTypesProvider _parameterTypesProvider; private readonly MethodInfo _baseGetParameterMethod; private readonly Dictionary _methodParametersMap = new(); + private readonly Dictionary> _methodIdParametersMap = new(); private readonly object[] _tempResolveParams = new object[1]; internal MethodResolver(ProvidersDto providersDto, BindingFlags flags) @@ -39,9 +40,31 @@ internal void Resolve(object consumer, Type consumerType, int? id = null) } } + internal void ClearGlobalCache() + { + _methodParametersMap.Clear(); + } + + internal void ClearLocalCache() + { + _methodIdParametersMap.Clear(); + } + + internal void ClearLocalCache(int id) + { + _methodIdParametersMap.Remove(id); + } + private void ResolveMethod(object consumer, MethodInfo methodInfo, int? id = null) { - if (!_methodParametersMap.TryGetValue(methodInfo, out object[] methodParameters)) + if (id != null && !_methodIdParametersMap.ContainsKey(id.Value)) + { + _methodIdParametersMap.Add(id.Value, new Dictionary()); + } + + var map = id == null ? _methodParametersMap : _methodIdParametersMap[id.Value]; + + if (!map.TryGetValue(methodInfo, out object[] methodParameters)) { var injectedParameterTypes = _parameterTypesProvider.GetParameterTypes(methodInfo); methodParameters = new object[injectedParameterTypes.Length]; @@ -52,7 +75,7 @@ private void ResolveMethod(object consumer, MethodInfo methodInfo, int? id = nul var getInstance = _genericMethodsProvider.GetParameterInstanceMethod(_baseGetParameterMethod, injectedParameterTypes[i]); methodParameters[i] = getInstance.Invoke(this, _tempResolveParams); } - _methodParametersMap.Add(methodInfo, methodParameters); + map.Add(methodInfo, methodParameters); } methodInfo.Invoke(consumer, methodParameters); } diff --git a/Assets/UniDI/Scripts/Strategies/ResolvingStrategy.cs b/Assets/UniDI/Scripts/Strategies/ResolvingStrategy.cs index 2eb5d5f..8ebe28b 100644 --- a/Assets/UniDI/Scripts/Strategies/ResolvingStrategy.cs +++ b/Assets/UniDI/Scripts/Strategies/ResolvingStrategy.cs @@ -39,5 +39,20 @@ internal void Resolve(object consumer, int? id = null) _propertyResolver.Resolve(consumer, consumerType, id); _methodResolver.Resolve(consumer, consumerType, id); } + + internal void ClearGlobalCache() + { + _methodResolver.ClearGlobalCache(); + } + + internal void ClearLocalCache() + { + _methodResolver.ClearLocalCache(); + } + + internal void ClearLocalCache(int id) + { + _methodResolver.ClearLocalCache(id); + } } } diff --git a/Assets/UniDI/Scripts/UniDIContext.cs b/Assets/UniDI/Scripts/UniDIContext.cs index d9b5a9f..c1dbc6d 100644 --- a/Assets/UniDI/Scripts/UniDIContext.cs +++ b/Assets/UniDI/Scripts/UniDIContext.cs @@ -54,16 +54,20 @@ internal void Inject(T injected, int id, Lifetime lifetime) internal void ReleaseDependency(Type type) { _instancesProvider.ClearInstances(type); + _resolvingStrategy.ClearGlobalCache(); } internal void ReleaseDependency(Type type, int id, bool clearFullScope) { _instancesProvider.ClearInstancesById(type, id, clearFullScope); + _resolvingStrategy.ClearLocalCache(id); } private void OnActiveSceneChanged(Scene current, Scene next) { _instancesProvider.ClearSceneInstances(); + _resolvingStrategy.ClearGlobalCache(); + _resolvingStrategy.ClearLocalCache(); } } } diff --git a/Assets/UniDI/package.json b/Assets/UniDI/package.json index aa8c56a..9c1dc9f 100644 --- a/Assets/UniDI/package.json +++ b/Assets/UniDI/package.json @@ -2,7 +2,7 @@ "name": "com.arty-f.unidi", "displayName": "UniDI", "author": { "name": "arty-F" }, - "version": "1.1.0", + "version": "1.1.1", "unity": "2021.3", "description": "Fast and easy Unity DI library.", "keywords": [ "DI", "Dependency Injection", "DI Container" ], diff --git a/Assets/UniDITestScripts/LocalScopeTests.meta b/Assets/UniDITestScripts/LocalScopeTests.meta new file mode 100644 index 0000000..c6b68e6 --- /dev/null +++ b/Assets/UniDITestScripts/LocalScopeTests.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 47ccba44db8bbb347a75860e7f5a91bc +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UniDITestScripts/LocalScopeTests/LocalConsumerClass.cs b/Assets/UniDITestScripts/LocalScopeTests/LocalConsumerClass.cs new file mode 100644 index 0000000..0314501 --- /dev/null +++ b/Assets/UniDITestScripts/LocalScopeTests/LocalConsumerClass.cs @@ -0,0 +1,13 @@ +namespace UniDI.Test +{ + public class LocalConsumerClass + { + public LocalInjectedClass LocalInjectedClass; + + [Inject] + private void Init(LocalInjectedClass localInjectedClass) + { + LocalInjectedClass = localInjectedClass; + } + } +} diff --git a/Assets/UniDITestScripts/LocalScopeTests/LocalConsumerClass.cs.meta b/Assets/UniDITestScripts/LocalScopeTests/LocalConsumerClass.cs.meta new file mode 100644 index 0000000..2cdba95 --- /dev/null +++ b/Assets/UniDITestScripts/LocalScopeTests/LocalConsumerClass.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: bf26af4bfeb37d743ad4ad4cfb0ad626 \ No newline at end of file diff --git a/Assets/UniDITestScripts/LocalScopeTests/LocalInjectedClass.cs b/Assets/UniDITestScripts/LocalScopeTests/LocalInjectedClass.cs new file mode 100644 index 0000000..9e3bf80 --- /dev/null +++ b/Assets/UniDITestScripts/LocalScopeTests/LocalInjectedClass.cs @@ -0,0 +1,12 @@ +namespace UniDI.Test +{ + public class LocalInjectedClass + { + public int Value; + + public LocalInjectedClass(int value) + { + Value = value; + } + } +} diff --git a/Assets/UniDITestScripts/LocalScopeTests/LocalInjectedClass.cs.meta b/Assets/UniDITestScripts/LocalScopeTests/LocalInjectedClass.cs.meta new file mode 100644 index 0000000..9d9f8b8 --- /dev/null +++ b/Assets/UniDITestScripts/LocalScopeTests/LocalInjectedClass.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 4bc79c8fad5351448bf947f669db2707 \ No newline at end of file diff --git a/Assets/UniDITestScripts/LocalScopeTests/LocalScopeTester.cs b/Assets/UniDITestScripts/LocalScopeTests/LocalScopeTester.cs new file mode 100644 index 0000000..89f843c --- /dev/null +++ b/Assets/UniDITestScripts/LocalScopeTests/LocalScopeTester.cs @@ -0,0 +1,23 @@ +using UnityEngine; + +namespace UniDI.Test +{ + public class LocalScopeTester : MonoBehaviour + { + private void Start() + { + var injected1 = new LocalInjectedClass(1); + var injected2 = new LocalInjectedClass(2); + injected1.Inject(1); + injected2.Inject(2); + + var consumer1 = new LocalConsumerClass(); + var consumer2 = new LocalConsumerClass(); + consumer1.Resolve(1); + consumer2.Resolve(2); + + Debug.Log($"consumer1: {consumer1.LocalInjectedClass.Value}"); + Debug.Log($"consumer2: {consumer2.LocalInjectedClass.Value}"); + } + } +} diff --git a/Assets/UniDITestScripts/LocalScopeTests/LocalScopeTester.cs.meta b/Assets/UniDITestScripts/LocalScopeTests/LocalScopeTester.cs.meta new file mode 100644 index 0000000..5719594 --- /dev/null +++ b/Assets/UniDITestScripts/LocalScopeTests/LocalScopeTester.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 3a99b13ce29beec4b870bb953e8df2ff \ No newline at end of file diff --git a/Assets/UniDITestScripts/PerformanceTests/PerformanceTestStarter.cs b/Assets/UniDITestScripts/PerformanceTests/PerformanceTestStarter.cs index adc77b9..8b18c2c 100644 --- a/Assets/UniDITestScripts/PerformanceTests/PerformanceTestStarter.cs +++ b/Assets/UniDITestScripts/PerformanceTests/PerformanceTestStarter.cs @@ -1,5 +1,4 @@ -using Assets.UniDITestScripts; -using System.Collections; +using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; diff --git a/Assets/UniDITestScripts/PerformanceTests/PerformanceTester.cs b/Assets/UniDITestScripts/PerformanceTests/PerformanceTester.cs index 34e63d9..321b333 100644 --- a/Assets/UniDITestScripts/PerformanceTests/PerformanceTester.cs +++ b/Assets/UniDITestScripts/PerformanceTests/PerformanceTester.cs @@ -1,10 +1,8 @@ -using UniDI; -using UniDI.Test; -using System.Collections.Generic; +using System.Collections.Generic; using System.Diagnostics; using UnityEngine; -namespace Assets.UniDITestScripts +namespace UniDI.Test { public class PerformanceTester : MonoBehaviour {