public IEnumerable<ConstructorCallWeave> FindConstructorCallWeaves(IAssembly assembly, FactoryMap factories)
 {
     List<ConstructorCallWeave> spots = new List<ConstructorCallWeave>();
       foreach (TypeDefinition type in GetTypes(assembly, factories))
       {
     foreach (MethodDefinition method in type.Methods)
     {
       if (method.Body == null)
       {
     continue;
       }
       foreach (Instruction instruction in method.Body.Instructions)
       {
     if (instruction.OpCode == OpCodes.Newobj)
     {
       MethodDefinition constructor = instruction.Operand as MethodDefinition;
       if (constructor != null && constructor.Parameters.Count == 0)
       {
         if (factories.HasForObjectType(constructor.DeclaringType))
         {
           spots.Add(new ConstructorCallWeave(assembly, method, instruction, constructor));
         }
       }
     }
       }
     }
       }
       return spots;
 }
        public void StoreFactoryMap(IAssembly assembly, FactoryMap factoryMap)
        {
            MethodInfo getTypeFromHandleReflect = typeof (Type).GetMethod("GetTypeFromHandle", new Type[] { typeof(RuntimeTypeHandle) });
              MethodReference getTypeFromHandle = assembly.Import(getTypeFromHandleReflect);
              TypeReference systemType = assembly.Import(typeof(Type));
              TypeReference arrayOfTypes = assembly.Import(typeof(Type[]));
              TypeReference arrayOfArrayOfTypes = assembly.Import(typeof(Type[][]));

              // Now we create the actual type and stuff...
              TypeDefinition mapType = GetFactoryMapType(assembly);
              MethodDefinition getFactoriesMethod = new MethodDefinition(FactoryMapMethodName, MethodAttributes.Public, arrayOfArrayOfTypes);
              getFactoriesMethod.IsVirtual = true;
              mapType.Methods.Add(getFactoriesMethod);

              getFactoriesMethod.Body.Variables.Add(new VariableDefinition("map", 0, getFactoriesMethod, arrayOfArrayOfTypes));
              getFactoriesMethod.Body.Variables.Add(new VariableDefinition("row", 1, getFactoriesMethod, arrayOfTypes));
              getFactoriesMethod.Body.InitLocals = true;

              CilWorker worker = getFactoriesMethod.Body.CilWorker;
              List<Factory> factories = new List<Factory>(factoryMap.Factories);
              worker.Append(worker.Create(OpCodes.Nop));
              worker.Append(worker.Create(OpCodes.Ldc_I4, factories.Count));
              worker.Append(worker.Create(OpCodes.Newarr, arrayOfTypes));
              worker.Append(worker.Create(OpCodes.Stloc_0));
              worker.Append(worker.Create(OpCodes.Ldloc_0));

              int index = 0;
              foreach (Factory factory in factories)
              {
            worker.Append(worker.Create(OpCodes.Ldc_I4, index));

            worker.Append(worker.Create(OpCodes.Ldc_I4, 2));
            worker.Append(worker.Create(OpCodes.Newarr, systemType));
            worker.Append(worker.Create(OpCodes.Stloc_1));

            worker.Append(worker.Create(OpCodes.Ldloc_1));
            worker.Append(worker.Create(OpCodes.Ldc_I4_0));
            worker.Append(worker.Create(OpCodes.Ldtoken, factory.ObjectType));
            worker.Append(worker.Create(OpCodes.Call, getTypeFromHandle));
            worker.Append(worker.Create(OpCodes.Stelem_Ref));

            worker.Append(worker.Create(OpCodes.Ldloc_1));
            worker.Append(worker.Create(OpCodes.Ldc_I4_1));
            worker.Append(worker.Create(OpCodes.Ldtoken, factory.FactoryType));
            worker.Append(worker.Create(OpCodes.Call, getTypeFromHandle));
            worker.Append(worker.Create(OpCodes.Stelem_Ref));

            worker.Append(worker.Create(OpCodes.Ldloc_1));
            worker.Append(worker.Create(OpCodes.Stelem_Ref));
            index++;
            worker.Append(worker.Create(OpCodes.Ldloc_0));
              }

              worker.Append(worker.Create(OpCodes.Ret));
              assembly.Inject(mapType);
        }
 private static IEnumerable<TypeDefinition> GetTypes(IAssembly assembly, FactoryMap factories)
 {
     foreach (TypeDefinition type in assembly.Types)
       {
     if (!factories.HasForFactoryType(type))
     {
       yield return type;
     }
       }
 }
Exemple #4
0
 public FactoryMap FindFactories(IAssembly assembly)
 {
     FactoryMap map = new FactoryMap();
       foreach (TypeDefinition type in assembly.Types)
       {
     TypeReference objectIsFactoryFor = IsFactory(type);
     if (objectIsFactoryFor != null)
     {
       _log.Log("Found {0} as factory for {1}", type.FullName, objectIsFactoryFor.FullName);
       map.AddFactory(objectIsFactoryFor, type);
     }
       }
       return map;
 }
        public void WeaveConstructorCalls(IEnumerable<ConstructorCallWeave> weaves, FactoryMap factories)
        {
            MethodInfo getFactoryMethod = typeof(Factories).GetMethod("Create");
              foreach (ConstructorCallWeave weave in weaves)
              {
            Factory factory = factories.GetForObjectType(weave.Constructor.DeclaringType);
            _log.Log("Weaving {0} in {1}", factory.ObjectType, weave.ParentMethod);

            MethodReference getObjectMethodReference = weave.ParentAssembly.Import(getFactoryMethod);
            GenericInstanceMethod methodCall = new GenericInstanceMethod(getObjectMethodReference);
            methodCall.GenericArguments.Add(factory.ObjectType);

            CilWorker worker = weave.ParentMethod.Body.CilWorker;
            Instruction callGetFactory = worker.Create(OpCodes.Call, methodCall);
            worker.Replace(weave.NewInstruction, callGetFactory);
              }
        }