/// <summary> /// Creates a method that matches the signature defined in the /// <paramref name="method"/> parameter. /// </summary> /// <param name="targetType">The type that will host the new method.</param> /// <param name="method">The method from which the signature will be derived.</param> public virtual MethodDefinition CreateMethod(TypeDefinition targetType, MethodInfo method) { #region Match the method signature ModuleDefinition module = targetType.Module; string methodName = method.Name; // If the method is a member defined on an interface type, // we need to rename the method to avoid // any naming conflicts in the type itself if (method.DeclaringType.IsInterface) { string parentName = method.DeclaringType.FullName; // Rename the parent type to its fully qualified name // if it is a generic type methodName = string.Format("{0}.{1}", parentName, methodName); } MethodAttributes baseAttributes = MethodAttributes.Virtual | MethodAttributes.HideBySig; MethodAttributes attributes = default(MethodAttributes); #region Match the visibility of the target method if (method.IsFamilyOrAssembly) attributes = baseAttributes | MethodAttributes.FamORAssem; if (method.IsFamilyAndAssembly) attributes = baseAttributes | MethodAttributes.FamANDAssem; if (method.IsPublic) attributes = baseAttributes | MethodAttributes.Public; #endregion // Build the list of parameter types Type[] parameterTypes = (from param in method.GetParameters() let type = param.ParameterType let importedType = type select importedType).ToArray(); //Build the list of generic parameter types Type[] genericParameterTypes = method.GetGenericArguments(); MethodDefinition newMethod = targetType.DefineMethod(methodName, attributes, method.ReturnType, parameterTypes, genericParameterTypes); newMethod.Body.InitLocals = true; newMethod.ImplAttributes = MethodImplAttributes.IL | MethodImplAttributes.Managed; newMethod.HasThis = true; // Match the generic type arguments Type[] typeArguments = method.GetGenericArguments(); if (typeArguments != null || typeArguments.Length > 0) MatchGenericArguments(newMethod, typeArguments); MethodReference originalMethodRef = module.Import(method); newMethod.Overrides.Add(originalMethodRef); #endregion // Define the method body if (Emitter != null) Emitter.Emit(method, newMethod); return newMethod; }
/// <summary> /// Defines the factory method on the singleton type. /// </summary> /// <param name="singletonType">The singleton type that will be generated by the emitter.</param> /// <param name="il">The <see cref="ILProcessor"/> instance that points to the target method body.</param> /// <param name="instanceField">The static field that holds the singleton instance.</param> /// <returns>The singleton type's GetInstance method.</returns> private MethodDefinition DefineGetInstance(TypeDefinition singletonType, ILProcessor il, FieldDefinition instanceField) { // Define the GetInstance method on the singleton type var getInstanceMethodAttributes = MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig; var getInstanceMethod = singletonType.DefineMethod("GetInstance", getInstanceMethodAttributes, typeof(object), new System.Type[0], new System.Type[0]); var singletonWorker = getInstanceMethod.GetILGenerator(); singletonWorker.Emit(OpCodes.Ldsfld, instanceField); singletonWorker.Emit(OpCodes.Ret); return getInstanceMethod; }