From 589eb66fa245e7d060edbdbb02fbdd46681363c8 Mon Sep 17 00:00:00 2001 From: Denis Lazarev Date: Thu, 13 May 2021 17:34:21 +0700 Subject: [PATCH 1/2] Injection order is reversed https://github.com/hadashiA/VContainer/issues/217 --- .../Assets/VContainer/Runtime/Internal/ReflectionInjector.cs | 4 ++-- VContainer/Assets/VContainer/Tests/ContainerTest.cs | 2 ++ VContainer/Assets/VContainer/Tests/Fixtures.cs | 4 ++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/VContainer/Assets/VContainer/Runtime/Internal/ReflectionInjector.cs b/VContainer/Assets/VContainer/Runtime/Internal/ReflectionInjector.cs index ed55d1fc..f91aefee 100644 --- a/VContainer/Assets/VContainer/Runtime/Internal/ReflectionInjector.cs +++ b/VContainer/Assets/VContainer/Runtime/Internal/ReflectionInjector.cs @@ -20,9 +20,9 @@ public static ReflectionInjector Build(Type type) public void Inject(object instance, IObjectResolver resolver, IReadOnlyList parameters) { - InjectMethods(instance, resolver, parameters); - InjectProperties(instance, resolver); InjectFields(instance, resolver); + InjectProperties(instance, resolver); + InjectMethods(instance, resolver, parameters); } public object CreateInstance(IObjectResolver resolver, IReadOnlyList parameters) diff --git a/VContainer/Assets/VContainer/Tests/ContainerTest.cs b/VContainer/Assets/VContainer/Tests/ContainerTest.cs index 34f30047..c7eec057 100644 --- a/VContainer/Assets/VContainer/Tests/ContainerTest.cs +++ b/VContainer/Assets/VContainer/Tests/ContainerTest.cs @@ -163,6 +163,8 @@ public void ResolveAllInjectableFeatures() Assert.That(((AllInjectionFeatureService)obj1).ConstructorCalled, Is.True); Assert.That(((AllInjectionFeatureService)obj1).Method1Called, Is.True); Assert.That(((AllInjectionFeatureService)obj1).Method2Called, Is.True); + Assert.That(((AllInjectionFeatureService)obj1).MethodCalledAfterFieldInjected, Is.True); + Assert.That(((AllInjectionFeatureService)obj1).MethodCalledAfterPropertyInjected, Is.True); Assert.That(((AllInjectionFeatureService)obj1).GetPrivateProperty(), Is.InstanceOf()); Assert.That(((AllInjectionFeatureService)obj1).PublicPropertyInjectable, Is.InstanceOf()); Assert.That(((AllInjectionFeatureService)obj1).GetPrivateFieldInjectable(), Is.InstanceOf()); diff --git a/VContainer/Assets/VContainer/Tests/Fixtures.cs b/VContainer/Assets/VContainer/Tests/Fixtures.cs index 90976434..654cc2a3 100644 --- a/VContainer/Assets/VContainer/Tests/Fixtures.cs +++ b/VContainer/Assets/VContainer/Tests/Fixtures.cs @@ -35,6 +35,8 @@ class AllInjectionFeatureService : I1 public bool ConstructorCalled; public bool Method1Called; public bool Method2Called; + public bool MethodCalledAfterFieldInjected; + public bool MethodCalledAfterPropertyInjected; I2 privateProperty; @@ -78,12 +80,14 @@ public AllInjectionFeatureService(I6 fromConstructor1, I7 fromConstructor2) public void MethodInjectable1(I3 service3, I4 service4) { Method1Called = true; + MethodCalledAfterFieldInjected = privateFieldInjectable != null; } [Inject] public void MethodInjectable2(I5 service5, I6 service6) { Method2Called = true; + MethodCalledAfterPropertyInjected = privateProperty != null; } public I4 GetPrivateFieldInjectable() => privateFieldInjectable; From 95a855f9729019f58b01373b8e0f283f2674da9d Mon Sep 17 00:00:00 2001 From: Denis Lazarev Date: Thu, 13 May 2021 17:59:37 +0700 Subject: [PATCH 2/2] Injection order is reversed in IL generator https://github.com/hadashiA/VContainer/issues/217 --- .../Editor/CodeGen/InjectionILGenerator.cs | 70 +++++++++---------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/VContainer/Assets/VContainer/Editor/CodeGen/InjectionILGenerator.cs b/VContainer/Assets/VContainer/Editor/CodeGen/InjectionILGenerator.cs index 3c282fea..7087e59b 100644 --- a/VContainer/Assets/VContainer/Editor/CodeGen/InjectionILGenerator.cs +++ b/VContainer/Assets/VContainer/Editor/CodeGen/InjectionILGenerator.cs @@ -335,33 +335,22 @@ void GenerateInjectMethod(TypeDefinition typeDef, TypeDefinition injectorTypeDef processor.Emit(OpCodes.Stloc_S, instanceVariableDef); } - if (injectTypeInfo.InjectMethods != null) + if (injectTypeInfo.InjectFields != null) { - foreach (var injectMethod in injectTypeInfo.InjectMethods) + foreach (var injectField in injectTypeInfo.InjectFields) { - var injectMethodRef = module.ImportReference(injectMethod.MethodInfo); - processor.Emit(OpCodes.Ldloc_S, instanceVariableDef); - for (var i = 0; i < injectMethodRef.Parameters.Count; i++) - { - var paramDef = injectMethodRef.Parameters[i]; - var paramInfo = injectMethod.ParameterInfos[i]; - var paramTypeRef = Utils.CreateParameterTypeReference(module, paramInfo.ParameterType, typeDef); + var fieldRef = module.ImportReference(injectField); + var fieldTypeRef = Utils.CreateParameterTypeReference(module, injectField.FieldType, typeDef); - var paramVariableDef = new VariableDefinition(paramDef.ParameterType); - body.Variables.Add(paramVariableDef); + processor.Emit(OpCodes.Ldloc_S, instanceVariableDef); - // TODO: Add ExceptionHandler - processor.Emit(OpCodes.Ldarg_2); - processor.Emit(OpCodes.Ldtoken, paramTypeRef); - processor.Emit(OpCodes.Call, GetTypeFromHandleRef); - processor.Emit(OpCodes.Ldstr, paramInfo.Name); - processor.Emit(OpCodes.Ldarg_3); - processor.Emit(OpCodes.Call, ResolveOrParameterMethodRef); - processor.Emit(OpCodes.Unbox_Any, paramTypeRef); - processor.Emit(OpCodes.Stloc_S, paramVariableDef); - processor.Emit(OpCodes.Ldloc_S, paramVariableDef); - } - processor.Emit(OpCodes.Callvirt, injectMethodRef); + // TODO: Add ExceptionHandler + // instance.Field = resolver.Resolve(Type) + processor.Emit(OpCodes.Ldarg_2); + processor.Emit(OpCodes.Ldtoken, fieldTypeRef); + processor.Emit(OpCodes.Call, GetTypeFromHandleRef); + processor.Emit(OpCodes.Call, ResolveMethodRef); + processor.Emit(OpCodes.Stfld, fieldRef); } } @@ -384,22 +373,33 @@ void GenerateInjectMethod(TypeDefinition typeDef, TypeDefinition injectorTypeDef } } - if (injectTypeInfo.InjectFields != null) + if (injectTypeInfo.InjectMethods != null) { - foreach (var injectField in injectTypeInfo.InjectFields) + foreach (var injectMethod in injectTypeInfo.InjectMethods) { - var fieldRef = module.ImportReference(injectField); - var fieldTypeRef = Utils.CreateParameterTypeReference(module, injectField.FieldType, typeDef); - + var injectMethodRef = module.ImportReference(injectMethod.MethodInfo); processor.Emit(OpCodes.Ldloc_S, instanceVariableDef); + for (var i = 0; i < injectMethodRef.Parameters.Count; i++) + { + var paramDef = injectMethodRef.Parameters[i]; + var paramInfo = injectMethod.ParameterInfos[i]; + var paramTypeRef = Utils.CreateParameterTypeReference(module, paramInfo.ParameterType, typeDef); - // TODO: Add ExceptionHandler - // instance.Field = resolver.Resolve(Type) - processor.Emit(OpCodes.Ldarg_2); - processor.Emit(OpCodes.Ldtoken, fieldTypeRef); - processor.Emit(OpCodes.Call, GetTypeFromHandleRef); - processor.Emit(OpCodes.Call, ResolveMethodRef); - processor.Emit(OpCodes.Stfld, fieldRef); + var paramVariableDef = new VariableDefinition(paramDef.ParameterType); + body.Variables.Add(paramVariableDef); + + // TODO: Add ExceptionHandler + processor.Emit(OpCodes.Ldarg_2); + processor.Emit(OpCodes.Ldtoken, paramTypeRef); + processor.Emit(OpCodes.Call, GetTypeFromHandleRef); + processor.Emit(OpCodes.Ldstr, paramInfo.Name); + processor.Emit(OpCodes.Ldarg_3); + processor.Emit(OpCodes.Call, ResolveOrParameterMethodRef); + processor.Emit(OpCodes.Unbox_Any, paramTypeRef); + processor.Emit(OpCodes.Stloc_S, paramVariableDef); + processor.Emit(OpCodes.Ldloc_S, paramVariableDef); + } + processor.Emit(OpCodes.Callvirt, injectMethodRef); } }