/src/LinFu.IoC/Configuration/MethodBuilder.cs
http://github.com/philiplaureano/LinFu · C# · 83 lines · 42 code · 10 blank · 31 comment · 3 complexity · 21966a1347bccc1b2246724df339e35d MD5 · raw file
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Reflection;
- using System.Reflection.Emit;
- namespace LinFu.IoC.Configuration
- {
- /// <summary>
- /// A class that dynamically generates calls to a <see cref="MethodInfo" /> instance.
- /// </summary>
- public class MethodBuilder : BaseMethodBuilder<MethodInfo>
- {
- /// <summary>
- /// Pushes the method target onto the evaluation stack.
- /// </summary>
- /// <param name="IL">The <see cref="ILGenerator" /> of the method body.</param>
- /// <param name="method">The target method.</param>
- protected override void PushInstance(ILGenerator IL, MethodInfo method)
- {
- if (method.IsStatic)
- return;
- IL.Emit(OpCodes.Ldarg_0);
- }
- /// <summary>
- /// Pushes the method arguments onto the stack.
- /// </summary>
- /// <param name="IL">The <see cref="ILGenerator" /> of the target method body.</param>
- /// <param name="targetMethod">The target method that will be invoked.</param>
- protected override void PushMethodArguments(ILGenerator IL, MethodBase targetMethod)
- {
- var parameterTypes = (from p in targetMethod.GetParameters()
- select p.ParameterType).ToArray();
- var offset = targetMethod.IsStatic ? 0 : 1;
- // Push the method arguments onto the stack
- var parameterCount = parameterTypes.Length;
- for (var index = 0; index < parameterCount; index++) IL.Emit(OpCodes.Ldarg, index + offset);
- }
- /// <summary>
- /// Determines the return type from the target <paramref name="method" />.
- /// </summary>
- /// <param name="method">The target method itself.</param>
- /// <returns>The method return type.</returns>
- protected override Type GetReturnType(MethodInfo method)
- {
- return method.ReturnType;
- }
- /// <summary>
- /// Determines the parameter types of the dynamically generated method.
- /// </summary>
- /// <param name="existingMethod">The target method.</param>
- /// <param name="parameterTypes">The target method argument types.</param>
- /// <returns>The list of <see cref="System.Type" /> objects that describe the signature of the method to generate.</returns>
- /// <remarks>This override will add an additional parameter type to accomodate the method target.</remarks>
- protected override IList<Type> GetParameterList(MethodInfo existingMethod, Type[] parameterTypes)
- {
- var parameterList = new List<Type>();
- if (!existingMethod.IsStatic)
- parameterList.Add(existingMethod.DeclaringType);
- parameterList.AddRange(parameterTypes);
- return parameterList;
- }
- /// <summary>
- /// Emits the instruction to call the target <paramref name="method" />
- /// </summary>
- /// <param name="IL">The <see cref="ILGenerator" /> of the target method body.</param>
- /// <param name="method">The method that will be invoked.</param>
- protected override void EmitCall(ILGenerator IL, MethodInfo method)
- {
- var callInstruction = method.IsVirtual ? OpCodes.Callvirt : OpCodes.Call;
- IL.Emit(callInstruction, method);
- }
- }
- }