示例#1
0
 public AsyncMethodInterceptorWeaver(WeaverContext context, TypeReference methodInterceptorInterface,
                                     MethodReference asyncInvokerWrap, MethodReference asyncInvokerUnwrap)
     : base(context)
 {
     baseInvoke              = ModuleDefinition.FindMethod(methodInterceptorInterface, "InvokeAsync");
     this.asyncInvokerWrap   = asyncInvokerWrap;
     this.asyncInvokerUnwrap = asyncInvokerUnwrap;
 }
示例#2
0
        public EventInterceptorWeaver(WeaverContext context) : base(context)
        {
            var eventAddInterceptorInterface    = FindType("Someta", "IEventAddInterceptor");
            var eventRemoveInterceptorInterface = FindType("Someta", "IEventRemoveInterceptor");

            addEventHandler    = ModuleDefinition.FindMethod(eventAddInterceptorInterface, "AddEventHandler");
            removeEventHandler = ModuleDefinition.FindMethod(eventRemoveInterceptorInterface, "RemoveEventHandler");
        }
示例#3
0
            public GlobalsType(ModuleDefinition module)
            {
                // The Solution constructor has a line like this:
                //     this.someField = new HashSet<int>[Globals.MaxTestRuns];
                // We use this to find the "Globals" type.
                var ctor  = module.FindMethod("Solution", ".ctor");
                var instr = ctor.Body.Instructions.Single(i => i.OpCode == OpCodes.Newarr && i.Operand?.ToString() == "System.Collections.Generic.HashSet`1<System.Int32>");

                Type             = ((FieldDefinition)instr.Previous.Operand).DeclaringType;
                ClassConstructor = Type.FindMethod(".cctor");

                // Find "MaxBoardSize = new Index2(22, 14)" and use that to get the MaxBoardSize field
                MaxBoardSize = (FieldDefinition)ClassConstructor.FindInstruction(OpCodes.Ldc_I4_S, (sbyte)14).FindNext(OpCodes.Stsfld).Operand;
            }
示例#4
0
 public MethodInterceptorWeaver(WeaverContext context, TypeReference methodInterceptorInterface, TypeReference asyncMethodInterceptorInterface)
     : base(context)
 {
     this.asyncMethodInterceptorInterface = asyncMethodInterceptorInterface;
     baseInvoke = ModuleDefinition.FindMethod(methodInterceptorInterface, "Invoke");
 }
示例#5
0
 public PropertyGetInterceptorWeaver(WeaverContext context, TypeReference propertyInterceptorInterface) : base(context)
 {
     baseGetPropertyValue = ModuleDefinition.FindMethod(propertyInterceptorInterface, "GetPropertyValue");
 }
示例#6
0
        public override void Execute()
        {
//            Debugger.Launch();

            var soMeta = ModuleDefinition.FindAssembly("Someta");

            CecilExtensions.LogInfo    = LogInfo;
            CecilExtensions.LogWarning = LogWarning;
            CecilExtensions.LogError   = LogError;
            CecilExtensions.Initialize(ModuleDefinition, TypeSystem, soMeta);

            var extensionPointInterface          = ModuleDefinition.FindType("Someta", "IExtensionPoint", soMeta);
            var stateExtensionPointInterface     = ModuleDefinition.FindType("Someta", "IStateExtensionPoint`1", soMeta, "T");
            var stateExtensionPointInterfaceBase = ModuleDefinition.FindType("Someta", "IStateExtensionPoint", soMeta);
            var propertyGetInterceptorInterface  = ModuleDefinition.FindType("Someta", "IPropertyGetInterceptor", soMeta);
            var propertySetInterceptorInterface  = ModuleDefinition.FindType("Someta", "IPropertySetInterceptor", soMeta);
            var eventAddInterceptorInterface     = ModuleDefinition.FindType("Someta", "IEventAddInterceptor", soMeta);
            var eventRemoveInterceptorInterface  = ModuleDefinition.FindType("Someta", "IEventRemoveInterceptor", soMeta);
            var methodInterceptorInterface       = ModuleDefinition.FindType("Someta", "IMethodInterceptor", soMeta);
            var asyncMethodInterceptorInterface  = ModuleDefinition.FindType("Someta", "IAsyncMethodInterceptor", soMeta);
            var nonPublicAccessInterface         = ModuleDefinition.FindType("Someta", "INonPublicAccess", soMeta);
            var asyncInvoker       = ModuleDefinition.FindType("Someta.Helpers", "AsyncInvoker", soMeta);
            var asyncInvokerWrap   = ModuleDefinition.FindMethod(asyncInvoker, "Wrap");
            var asyncInvokerUnwrap = ModuleDefinition.FindMethod(asyncInvoker, "Unwrap");
            var instanceInitializerInterfaceBase = ModuleDefinition.FindType("Someta", "IInstanceInitializer", soMeta);
            var instanceInitializerInterface     = ModuleDefinition.FindType("Someta", "IInstanceInitializer`1", soMeta, "T");
//            var interceptorScopeAttribute = ModuleDefinition.FindType("Someta", "InterceptorScopeAttribute", soMeta);
//            var requireScopeInterceptorInterface = ModuleDefinition.FindType("Someta", "IRequireScopeInterceptor", soMeta);

            var extensionPointScopesClass           = ModuleDefinition.FindType("Someta", "ExtensionPointScopes", soMeta);
            var extensionPointScopesClassDefinition = extensionPointScopesClass.Resolve();
//            var interceptorScopeInterface = interceptorScopesClassDefinition.NestedTypes.Single(x => x.Name == "Scope");
            var extensionPointScopePropertyInterface = extensionPointScopesClassDefinition.NestedTypes.Single(x => x.Name == "Property");
            var extensionPointScopeMethodInterface   = extensionPointScopesClassDefinition.NestedTypes.Single(x => x.Name == "Method");
            var extensionPointScopeClassInterface    = extensionPointScopesClassDefinition.NestedTypes.Single(x => x.Name == "Class");

            var propertyGetInterceptions = new List <(PropertyDefinition, ExtensionPointAttribute)>();
            var propertySetInterceptions = new List <(PropertyDefinition, ExtensionPointAttribute)>();
            var eventAddInterceptions    = new List <(EventDefinition, ExtensionPointAttribute)>();
            var eventRemoveInterceptions = new List <(EventDefinition, ExtensionPointAttribute)>();
            var methodInterceptions      = new List <(MethodDefinition, ExtensionPointAttribute)>();
            var asyncMethodInterceptions = new List <(MethodDefinition, ExtensionPointAttribute)>();
            var classEnhancers           = new List <(TypeDefinition, ExtensionPointAttribute)>();
            var stateInterceptions       = new List <(IMemberDefinition, ExtensionPointAttribute)>();
            var instanceInitializers     = new List <(IMemberDefinition, ExtensionPointAttribute)>();

            var propertyGetInterceptorWeaver = new PropertyGetInterceptorWeaver(CecilExtensions.Context, propertyGetInterceptorInterface);
            var propertySetInterceptorWeaver = new PropertySetInterceptorWeaver(CecilExtensions.Context, propertySetInterceptorInterface);
            var eventInterceptorWeaver       = new EventInterceptorWeaver(CecilExtensions.Context);
            var methodInterceptorWeaver      = new MethodInterceptorWeaver(CecilExtensions.Context, methodInterceptorInterface, asyncMethodInterceptorInterface);
            var asyncMethodInterceptorWeaver = new AsyncMethodInterceptorWeaver(CecilExtensions.Context, asyncMethodInterceptorInterface, asyncInvokerWrap, asyncInvokerUnwrap);
            var classEnhancerWeaver          = new ClassEnhancerWeaver(CecilExtensions.Context);
            var stateWeaver = new StateWeaver(CecilExtensions.Context);
            var instanceInitializerWeaver = new InstanceInitializerWeaver(CecilExtensions.Context);

            // unscopedInterface: If present, and if genericTypes is empty (meaning no specific scope was specified),
            // unscopedInterface will be checked as a fallback.
            bool HasScope(ExtensionPointAttribute interceptor, TypeReference interfaceType, ExtensionPointScope scope, TypeReference unscopedInterface = null)
            {
                var genericTypes = interceptor.AttributeType.FindGenericInterfaces(interfaceType).ToArray();

                foreach (var genericType in genericTypes)
                {
                    var           argument       = genericType.GenericArguments[0];
                    TypeReference scopeInterface = null;
                    switch (scope)
                    {
                    case ExtensionPointScope.Class:
                        scopeInterface = extensionPointScopeClassInterface;
                        break;

                    case ExtensionPointScope.Property:
                        scopeInterface = extensionPointScopePropertyInterface;
                        break;

                    case ExtensionPointScope.Method:
                        scopeInterface = extensionPointScopeMethodInterface;
                        break;
                    }

                    if (argument.CompareTo(scopeInterface))
                    {
                        return(true);
                    }
                }

                // If no scope was specified, we consider the scope satisfied if an unscoped version is satisfied
                // Furthermore, the scope must match the member type.
                var isScopeMatchedWithMember = interceptor.Scope == scope;

                return(unscopedInterface != null && genericTypes.Length == 0 && unscopedInterface.IsAssignableFrom(interceptor.AttributeType) && isScopeMatchedWithMember);
            }

            // Inventory candidate classes
            var allTypes = ModuleDefinition.GetAllTypes();
            var assemblyInterceptorAttributes = ModuleDefinition.Assembly
                                                .GetCustomAttributesIncludingSubtypes(extensionPointInterface)
                                                .ToArray();

            ExtensionPointAttribute[] assemblyInterceptors;

            // If we have any assembly-level interceptors, we create a special state class to hold the attribute instances (since attributes
            // can contain state, but getting attributes through reflection always returns a new instance.
            if (assemblyInterceptorAttributes.Any())
            {
//                Debugger.Launch();
                var assemblyState = new TypeDefinition("Someta", "AssemblyState", TypeAttributes.Public, TypeSystem.ObjectReference);
                ModuleDefinition.Types.Add(assemblyState);

/*
 *              var constructorWithTarget = new MethodDefinition(".ctor", MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, TypeSystem.VoidReference);
 *              constructorWithTarget.Body.Emit(il =>
 *              {
 *                  il.Emit(OpCodes.Ret);
 *              });
 *              assemblyState.Methods.Add(constructorWithTarget);
 */

                CecilExtensions.Context.AssemblyState = assemblyState;
                assemblyInterceptors = assemblyInterceptorAttributes
                                       .Select(x => new ExtensionPointAttribute(assemblyState, ModuleDefinition.Assembly, x, ModuleDefinition.Assembly.CustomAttributes.IndexOf(x), ExtensionPointScope.Assembly))
                                       .ToArray();

                foreach (var interceptor in assemblyInterceptors)
                {
                    var fieldName      = interceptor.AttributeType.FullName.Replace(".", "$");
                    var attributeField = new FieldDefinition(fieldName, FieldAttributes.Static | FieldAttributes.Public, interceptor.AttributeType);
                    var index          = ModuleDefinition.Assembly.CustomAttributes.IndexOf(interceptor.Attribute);
                    assemblyState.Fields.Add(attributeField);

                    assemblyState.EmitToStaticConstructor(il =>
                    {
                        il.EmitGetAssemblyAttributeByIndex(index, interceptor.AttributeType);
                        il.SaveField(attributeField);
                    });
                }
            }
            else
            {
                assemblyInterceptors = new ExtensionPointAttribute[0];
            }

//            var moduleInterceptors = ModuleDefinition
//                .GetCustomAttributesIncludingSubtypes(extensionPointInterface)
//                .Select(x => new ExtensionPointAttribute(null, ModuleDefinition, x, ModuleDefinition.CustomAttributes.IndexOf(x), ExtensionPointScope.Module))
//                .ToArray();
//            var assemblyAndModuleInterceptors = assemblyInterceptors.Concat(moduleInterceptors).ToArray();
            foreach (var type in allTypes)
            {
                // We can get into recursion scenarios if we allow extension points on extension points.  For now, let's naively prohibit this
                if (extensionPointInterface.IsAssignableFrom(type))
                {
                    continue;
                }

                var classInterceptors = type
                                        .GetCustomAttributesInAncestry(extensionPointInterface)
                                        .Select(x => new ExtensionPointAttribute(x.DeclaringType, x.DeclaringType, x.Attribute, x.DeclaringType.CustomAttributes.IndexOf(x.Attribute), ExtensionPointScope.Class))
                                        .Concat(assemblyInterceptors /*.Select(x => new ExtensionPointAttribute(type, x.DeclaringMember, x.Attribute, x.Index, x.Scope))*/)
                                        .ToArray();

                foreach (var classInterceptor in classInterceptors)
                {
                    LogInfo($"Found class interceptor {classInterceptor.AttributeType}");
                    if (nonPublicAccessInterface.IsAssignableFrom(classInterceptor.AttributeType))
                    {
                        LogInfo($"Discovered class enhancer {classInterceptor.AttributeType.FullName} at {type.FullName}");
                        classEnhancers.Add((type, classInterceptor));
                    }
                    if (HasScope(classInterceptor, stateExtensionPointInterface, ExtensionPointScope.Class, stateExtensionPointInterfaceBase))
                    {
                        LogInfo($"Discovered class state interceptor {classInterceptor.AttributeType.FullName} at {type.FullName}");
                        stateInterceptions.Add((type, classInterceptor));
                    }
                    if (HasScope(classInterceptor, instanceInitializerInterface, ExtensionPointScope.Class, instanceInitializerInterfaceBase))
                    {
                        LogInfo($"Discovered instance initializer {classInterceptor.AttributeType.FullName} at {type.FullName}");
                        instanceInitializers.Add((type, classInterceptor));
                    }
                }

                foreach (var property in type.Properties)
                {
                    var interceptors = property.GetCustomAttributesIncludingSubtypes(extensionPointInterface)
                                       .Select(x => new ExtensionPointAttribute(type, property, x, property.CustomAttributes.IndexOf(x), ExtensionPointScope.Property))
                                       .Concat(classInterceptors);
                    foreach (var interceptor in interceptors)
                    {
                        if (propertyGetInterceptorInterface.IsAssignableFrom(interceptor.AttributeType))
                        {
                            LogInfo($"Discovered property get interceptor {interceptor.AttributeType.FullName} at {type.FullName}.{property.Name}");
                            propertyGetInterceptions.Add((property, interceptor));
                        }
                        if (propertySetInterceptorInterface.IsAssignableFrom(interceptor.AttributeType))
                        {
                            LogInfo($"Discovered property set interceptor {interceptor.AttributeType.FullName} at {type.FullName}.{property.Name}");
                            propertySetInterceptions.Add((property, interceptor));
                        }
                        if (HasScope(interceptor, stateExtensionPointInterface, ExtensionPointScope.Property, stateExtensionPointInterfaceBase))
                        {
                            LogInfo($"Discovered property state interceptor {interceptor.AttributeType.FullName} at {type.FullName}.{property.Name}");
                            stateInterceptions.Add((property, interceptor));
                        }
                        if (HasScope(interceptor, instanceInitializerInterface, ExtensionPointScope.Property, instanceInitializerInterfaceBase))
                        {
                            LogInfo($"Discovered instance initializer {interceptor.AttributeType.FullName} at {type.FullName}");
                            instanceInitializers.Add((property, interceptor));
                        }
                    }
                }

                foreach (var @event in type.Events)
                {
//                    Debugger.Launch();
                    var interceptors = @event.GetCustomAttributesIncludingSubtypes(extensionPointInterface)
                                       .Select(x => new ExtensionPointAttribute(type, @event, x, @event.CustomAttributes.IndexOf(x), ExtensionPointScope.Event))
                                       .Concat(classInterceptors);

                    foreach (var interceptor in interceptors)
                    {
                        if (eventAddInterceptorInterface.IsAssignableFrom(interceptor.AttributeType))
                        {
                            LogInfo($"Discovered event add interceptor {interceptor.AttributeType.FullName} at {type.FullName}.{@event.Name}");
                            eventAddInterceptions.Add((@event, interceptor));
                        }
                        if (eventRemoveInterceptorInterface.IsAssignableFrom(interceptor.AttributeType))
                        {
                            LogInfo($"Discovered event remove interceptor {interceptor.AttributeType.FullName} at {type.FullName}.{@event.Name}");
                            eventRemoveInterceptions.Add((@event, interceptor));
                        }
                    }
                }

                foreach (var method in type.Methods.Where(x => !x.IsConstructor))
                {
                    var interceptors = method.GetCustomAttributesIncludingSubtypes(extensionPointInterface)
                                       .Select(x => new ExtensionPointAttribute(type, method, x, method.CustomAttributes.IndexOf(x), ExtensionPointScope.Method))
                                       .Concat(classInterceptors);
                    foreach (var interceptor in interceptors)
                    {
                        if (methodInterceptorInterface.IsAssignableFrom(interceptor.AttributeType))
                        {
                            LogInfo($"Discovered method interceptor {interceptor.AttributeType.FullName} at {type.FullName}.{method.Name}");
                            methodInterceptions.Add((method, interceptor));
                        }
                        if (asyncMethodInterceptorInterface.IsAssignableFrom(interceptor.AttributeType))
                        {
                            LogInfo($"Discovered async method interceptor {interceptor.AttributeType.FullName} at {type.FullName}.{method.Name}");
                            asyncMethodInterceptions.Add((method, interceptor));
                        }
                        if (HasScope(interceptor, stateExtensionPointInterface, ExtensionPointScope.Method, stateExtensionPointInterfaceBase))
                        {
                            LogInfo($"Discovered method state interceptor {interceptor.AttributeType.FullName} at {type.FullName}.{method.Name}");
                            stateInterceptions.Add((method, interceptor));
                        }
                        if (HasScope(interceptor, instanceInitializerInterface, ExtensionPointScope.Method, instanceInitializerInterfaceBase))
                        {
                            LogInfo($"Discovered instance initializer {interceptor.AttributeType.FullName} at {type.FullName}");
                            instanceInitializers.Add((method, interceptor));
                        }
                    }
                }
            }

            foreach (var(property, interceptor) in propertyGetInterceptions)
            {
                propertyGetInterceptorWeaver.Weave(property, interceptor);
            }

            foreach (var(property, interceptor) in propertySetInterceptions)
            {
                propertySetInterceptorWeaver.Weave(property, interceptor);
            }

            foreach (var(@event, interceptor) in eventAddInterceptions)
            {
                eventInterceptorWeaver.Weave(@event, interceptor, isAdd: true);
            }

            foreach (var(@event, interceptor) in eventRemoveInterceptions)
            {
                eventInterceptorWeaver.Weave(@event, interceptor, isAdd: false);
            }

            foreach (var(method, interceptor) in methodInterceptions)
            {
                methodInterceptorWeaver.Weave(method, interceptor);
            }

            foreach (var(method, interceptor) in asyncMethodInterceptions)
            {
                asyncMethodInterceptorWeaver.Weave(method, interceptor);
            }

            foreach (var(type, interceptor) in classEnhancers)
            {
                classEnhancerWeaver.Weave(type, interceptor);
            }

            foreach (var(member, interceptor) in stateInterceptions)
            {
                stateWeaver.Weave(member, interceptor);
            }

            foreach (var(type, interceptor) in instanceInitializers)
            {
                instanceInitializerWeaver.Weave(type, interceptor);
            }
        }
示例#7
0
        public void Execute()
        {
            var sexyProxy = ModuleDefinition.FindAssembly("SexyProxy");

            if (sexyProxy == null)
            {
                LogError("Could not find assembly: SexyProxy (" + string.Join(", ", ModuleDefinition.AssemblyReferences.Select(x => x.Name)) + ")");
                return;
            }

            var proxyAttribute = ModuleDefinition.FindType("SexyProxy", "ProxyAttribute", sexyProxy);

            if (proxyAttribute == null)
            {
                throw new Exception($"{nameof(proxyAttribute)} is null");
            }
            var proxyForAttribute   = ModuleDefinition.FindType("SexyProxy", "ProxyForAttribute", sexyProxy);
            var doNotProxyAttribute = ModuleDefinition.FindType("SexyProxy", "DoNotProxyAttribute", sexyProxy);
            var originalMethodAttributeConstructor = ModuleDefinition.FindConstructor(ModuleDefinition.FindType("SexyProxy", "OriginalMethodAttribute", sexyProxy));
            var reverseProxyInterface = ModuleDefinition.FindType("SexyProxy", "IReverseProxy", sexyProxy);
            var proxyInterface        = ModuleDefinition.FindType("SexyProxy", "IProxy", sexyProxy);

            var targetTypes = ModuleDefinition.GetAllTypes().Where(x => x.IsDefined(proxyAttribute, true) || reverseProxyInterface.IsAssignableFrom(x) || proxyInterface.IsAssignableFrom(x)).ToArray();

            // Get external proxy references
            var proxyFors = ModuleDefinition.Assembly.GetCustomAttributes(proxyForAttribute).Select(x => (TypeReference)x.ConstructorArguments.Single().Value).Select(x => x.Resolve()).ToArray();

            targetTypes = targetTypes.Concat(proxyFors).ToArray();

            var methodInfoType   = ModuleDefinition.Import(ModuleWeaver.FindType(typeof(MethodInfo).FullName));
            var propertyInfoType = ModuleDefinition.Import(ModuleWeaver.FindType(typeof(PropertyInfo).FullName));

            var func2Type   = ModuleDefinition.Import(ModuleWeaver.FindType(typeof(Func <,>).FullName));
            var action1Type = ModuleDefinition.Import(ModuleWeaver.FindType(typeof(Action <>).FullName));
            // for some reason this does not work:
            // var objectArrayType = ModuleDefinition.Import(ModuleWeaver.FindType(typeof(object[]).FullName));
            var objectArrayType                        = ModuleDefinition.Import(typeof(object[]));
            var taskType                               = ModuleDefinition.Import(ModuleWeaver.FindType(typeof(Task).FullName));
            var invocationTType                        = ModuleDefinition.FindType("SexyProxy", "InvocationT`1", sexyProxy, "T");
            var asyncInvocationTType                   = ModuleDefinition.FindType("SexyProxy", "AsyncInvocationT`1", sexyProxy, "T");
            var invocationHandlerType                  = ModuleDefinition.FindType("SexyProxy", "InvocationHandler", sexyProxy);
            var invocationHandlerIsHandlerActive       = ModuleDefinition.FindMethod(invocationHandlerType, "IsHandlerActive");
            var voidInvocationType                     = ModuleDefinition.FindType("SexyProxy", "VoidInvocation", sexyProxy);
            var voidInvocationConstructor              = ModuleDefinition.FindConstructor(voidInvocationType);
            var voidAsyncInvocationType                = ModuleDefinition.FindType("SexyProxy", "VoidAsyncInvocation", sexyProxy);
            var voidAsyncInvocationConstructor         = ModuleDefinition.FindConstructor(voidAsyncInvocationType);
            var voidInvokeMethod                       = ModuleDefinition.FindMethod(invocationHandlerType, "VoidInvoke");
            var asyncVoidInvokeMethod                  = ModuleDefinition.FindMethod(invocationHandlerType, "VoidAsyncInvoke");
            var invokeTMethod                          = ModuleDefinition.FindMethod(invocationHandlerType, "InvokeT");
            var asyncInvokeTMethod                     = ModuleDefinition.FindMethod(invocationHandlerType, "AsyncInvokeT");
            var objectType                             = ModuleDefinition.Import(ModuleWeaver.FindType(typeof(object).FullName));
            var proxyGetInvocationHandlerMethod        = ModuleDefinition.FindGetter(proxyInterface, "InvocationHandler");
            var reverseProxyGetInvocationHandlerMethod = ModuleDefinition.FindGetter(reverseProxyInterface, "InvocationHandler");
            var invocationType                         = ModuleDefinition.FindType("SexyProxy", "Invocation", sexyProxy);
            var invocationGetArguments                 = ModuleDefinition.FindGetter(invocationType, "Arguments");
            var invocationGetProxy                     = ModuleDefinition.FindGetter(invocationType, "Proxy");
            var asyncTaskMethodBuilder                 = ModuleDefinition.Import(ModuleWeaver.FindType(typeof(AsyncTaskMethodBuilder <>).FullName));
            var methodFinder                           = ModuleDefinition.FindType("SexyProxy.Reflection", "MethodFinder`1", sexyProxy, "T");
            var findMethod                             = ModuleDefinition.FindMethod(methodFinder, "FindMethod");
            var findProperty                           = ModuleDefinition.FindMethod(methodFinder, "FindProperty");

            var context = new WeaverContext
            {
                ModuleDefinition                       = ModuleDefinition,
                LogWarning                             = LogWarning,
                LogError                               = LogError,
                LogInfo                                = LogInfo,
                SexyProxy                              = sexyProxy,
                MethodInfoType                         = methodInfoType,
                PropertyInfoType                       = propertyInfoType,
                Action1Type                            = action1Type,
                AsyncInvocationTType                   = asyncInvocationTType,
                Func2Type                              = func2Type,
                InvocationTType                        = invocationTType,
                ObjectArrayType                        = objectArrayType,
                TaskType                               = taskType,
                AsyncInvokeTMethod                     = asyncInvokeTMethod,
                AsyncVoidInvokeMethod                  = asyncVoidInvokeMethod,
                InvocationHandlerType                  = invocationHandlerType,
                InvocationHandlerIsHandlerActive       = invocationHandlerIsHandlerActive,
                InvokeTMethod                          = invokeTMethod,
                ObjectType                             = objectType,
                VoidAsyncInvocationConstructor         = voidAsyncInvocationConstructor,
                VoidInvocationConstructor              = voidInvocationConstructor,
                VoidInvokeMethod                       = voidInvokeMethod,
                ProxyGetInvocationHandlerMethod        = proxyGetInvocationHandlerMethod,
                ReverseProxyGetInvocationHandlerMethod = reverseProxyGetInvocationHandlerMethod,
                InvocationType                         = invocationType,
                VoidInvocationType                     = voidInvocationType,
                VoidAsyncInvocationType                = voidAsyncInvocationType,
                InvocationGetArguments                 = invocationGetArguments,
                InvocationGetProxy                     = invocationGetProxy,
                AsyncTaskMethodBuilder                 = asyncTaskMethodBuilder,
                MethodFinder                           = methodFinder,
                FindMethod                             = findMethod,
                FindProperty                           = findProperty,
                DoNotProxyAttribute                    = doNotProxyAttribute,
                OriginalMethodAttributeConstructor     = originalMethodAttributeConstructor
            };

            foreach (var sourceType in targetTypes)
            {
                LogInfo($"Emitting proxy for {sourceType.FullName}");
                ClassWeaver classWeaver;

                if (sourceType.IsInterface)
                {
                    classWeaver = new InterfaceClassWeaver(context, sourceType);
                }
                else if (proxyInterface.IsAssignableFrom(sourceType))
                {
                    classWeaver = new InPlaceClassWeaver(context, sourceType);
                }
                else if (reverseProxyInterface.IsAssignableFrom(sourceType))
                {
                    classWeaver = new ReverseProxyClassWeaver(context, sourceType);
                }
                else
                {
                    classWeaver = new NonInterfaceClassWeaver(context, sourceType);
                }

                classWeaver.Execute();
            }
        }