Skip to content

Commit

Permalink
Merge pull request #227 from longbombus/dev/injection_order
Browse files Browse the repository at this point in the history
Injection order is reversed
  • Loading branch information
hadashiA committed May 15, 2021
2 parents f66d6b6 + 95a855f commit 9955faa
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 37 deletions.
70 changes: 35 additions & 35 deletions VContainer/Assets/VContainer/Editor/CodeGen/InjectionILGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

Expand All @@ -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);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ public static ReflectionInjector Build(Type type)

public void Inject(object instance, IObjectResolver resolver, IReadOnlyList<IInjectParameter> parameters)
{
InjectMethods(instance, resolver, parameters);
InjectProperties(instance, resolver);
InjectFields(instance, resolver);
InjectProperties(instance, resolver);
InjectMethods(instance, resolver, parameters);
}

public object CreateInstance(IObjectResolver resolver, IReadOnlyList<IInjectParameter> parameters)
Expand Down
2 changes: 2 additions & 0 deletions VContainer/Assets/VContainer/Tests/ContainerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<I2>());
Assert.That(((AllInjectionFeatureService)obj1).PublicPropertyInjectable, Is.InstanceOf<I3>());
Assert.That(((AllInjectionFeatureService)obj1).GetPrivateFieldInjectable(), Is.InstanceOf<I4>());
Expand Down
4 changes: 4 additions & 0 deletions VContainer/Assets/VContainer/Tests/Fixtures.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class AllInjectionFeatureService : I1
public bool ConstructorCalled;
public bool Method1Called;
public bool Method2Called;
public bool MethodCalledAfterFieldInjected;
public bool MethodCalledAfterPropertyInjected;

I2 privateProperty;

Expand Down Expand Up @@ -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;
Expand Down

1 comment on commit 9955faa

@vercel
Copy link

@vercel vercel bot commented on 9955faa May 15, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.