public bool CreateNewObjectMethod(AssemblyDefinition assembly, 
                                        MethodDefinition templateMethod, 
                                        IAssemblyTracker tracker, 
                                        INewTransformerInfoWrapper infoWrapper)
        {
            MethodDefinition factoryMethod = null;
              if ((factoryMethod = infoWrapper.GetFactoryMethod (templateMethod, assembly, tracker)) != null)
              {
            if (factoryMethod.GenericParameters.Count != 1 || factoryMethod.Parameters.Count != 1 || !factoryMethod.IsStatic)
              throw new ArgumentException ("Factory method to create object does not have correct signature [public static T Create<T> (ParamList)]");

            TypeReference returnType = templateMethod.DeclaringType;
            if (templateMethod.DeclaringType.HasGenericParameters)
            {
              returnType = new GenericInstanceType (templateMethod.DeclaringType);
              foreach (var a in templateMethod.DeclaringType.GenericParameters.ToArray ())
              {
            returnType.GenericParameters.Add (a);
            ((GenericInstanceType) returnType).GenericArguments.Add (a);
              }
            }

            var importedFactoryMethod = templateMethod.Module.Import (factoryMethod);
            var genericInstanceMethod = new GenericInstanceMethod (importedFactoryMethod);
            genericInstanceMethod.GenericArguments.Add (templateMethod.DeclaringType);

            var paramlistDef = factoryMethod.Parameters[0].ParameterType.Resolve ();
            var importedParamListCreateMethod = templateMethod.Module.Import (SearchParamListFactoryMethod (paramlistDef, templateMethod));

            if (importedParamListCreateMethod == null)
              throw new ArgumentException ("Factory method: no corresponding 'create' method could have been found. [argument count]");

            var newObjectMethod = new MethodDefinition (
                                                    infoWrapper.GetWrapperMethodName (templateMethod),
                                                    MethodAttributes.Public | MethodAttributes.Static, returnType
                                                    );
            var instructions = newObjectMethod.Body.Instructions;

            foreach (var param in templateMethod.Parameters)
            {
              newObjectMethod.Parameters.Add (param);
              instructions.Add (Instruction.Create (OpCodes.Ldarg, param));
            }

            instructions.Add(Instruction.Create (OpCodes.Call, importedParamListCreateMethod));
            instructions.Add(Instruction.Create (OpCodes.Call, genericInstanceMethod));

            instructions.Add (Instruction.Create (OpCodes.Ret));
            newObjectMethod.Body.OptimizeMacros ();

            newObjectMethod.IsHideBySig = true;
            templateMethod.DeclaringType.Methods.Add (newObjectMethod);
            return true;
              }
              return false;
        }
 private void GenerateNewObjectMethods(AssemblyDefinition assembly, TypeDefinition targetType)
 {
     foreach (var method in targetType.Methods.ToList())
     {
         if (method.IsConstructor &&
             !targetType.Methods.Any(m => (m.Name == _infoWrapper.GetWrapperMethodName(method) &&
                                           HaveSameParameters(method, m))))
         {
             if (_replacer.CreateNewObjectMethod(assembly, method, _tracker, _infoWrapper))
             {
                 method.IsPublic  = false;
                 method.IsPrivate = false;
                 method.IsFamily  = true;
                 _tracker.MarkModified(assembly);
             }
         }
     }
 }
        public bool CreateNewObjectMethod(AssemblyDefinition assembly,
                                          MethodDefinition templateMethod,
                                          IAssemblyTracker tracker,
                                          INewTransformerInfoWrapper infoWrapper)
        {
            MethodDefinition factoryMethod = null;

            if ((factoryMethod = infoWrapper.GetFactoryMethod(templateMethod, assembly, tracker)) != null)
            {
                if (factoryMethod.GenericParameters.Count != 1 || factoryMethod.Parameters.Count != 1 || !factoryMethod.IsStatic)
                {
                    throw new ArgumentException("Factory method to create object does not have correct signature [public static T Create<T> (ParamList)]");
                }

                TypeReference returnType = templateMethod.DeclaringType;
                if (templateMethod.DeclaringType.HasGenericParameters)
                {
                    returnType = new GenericInstanceType(templateMethod.DeclaringType);
                    foreach (var a in templateMethod.DeclaringType.GenericParameters.ToArray())
                    {
                        returnType.GenericParameters.Add(a);
                        ((GenericInstanceType)returnType).GenericArguments.Add(a);
                    }
                }

                var importedFactoryMethod = templateMethod.Module.Import(factoryMethod);
                var genericInstanceMethod = new GenericInstanceMethod(importedFactoryMethod);
                genericInstanceMethod.GenericArguments.Add(templateMethod.DeclaringType);

                var paramlistDef = factoryMethod.Parameters[0].ParameterType.Resolve();
                var importedParamListCreateMethod = templateMethod.Module.Import(SearchParamListFactoryMethod(paramlistDef, templateMethod));

                if (importedParamListCreateMethod == null)
                {
                    throw new ArgumentException("Factory method: no corresponding 'create' method could have been found. [argument count]");
                }


                var newObjectMethod = new MethodDefinition(
                    infoWrapper.GetWrapperMethodName(templateMethod),
                    MethodAttributes.Public | MethodAttributes.Static, returnType
                    );
                var instructions = newObjectMethod.Body.Instructions;

                foreach (var param in templateMethod.Parameters)
                {
                    newObjectMethod.Parameters.Add(param);
                    instructions.Add(Instruction.Create(OpCodes.Ldarg, param));
                }

                instructions.Add(Instruction.Create(OpCodes.Call, importedParamListCreateMethod));
                instructions.Add(Instruction.Create(OpCodes.Call, genericInstanceMethod));

                instructions.Add(Instruction.Create(OpCodes.Ret));
                newObjectMethod.Body.OptimizeMacros();

                newObjectMethod.IsHideBySig = true;
                templateMethod.DeclaringType.Methods.Add(newObjectMethod);
                return(true);
            }
            return(false);
        }