Пример #1
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(typeof(MethodInfo));
            var propertyInfoType = ModuleDefinition.Import(typeof(PropertyInfo));

            var func2Type = ModuleDefinition.Import(typeof(Func<,>));
            var action1Type = ModuleDefinition.Import(typeof(Action<>));
            var objectArrayType = ModuleDefinition.Import(typeof(object[]));
            var taskType = ModuleDefinition.Import(typeof(Task));
            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(typeof(object));
            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(typeof(AsyncTaskMethodBuilder<>));
            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();
            }
        }
Пример #2
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();
            }
        }
Пример #3
0
 public InPlaceMethodWeaver(InPlaceClassWeaver classWeaver, MethodDefinition method, string name, MethodDefinition staticConstructor) : base(classWeaver, method, name, staticConstructor)
 {
 }
Пример #4
0
 public InPlaceMethodWeaver(InPlaceClassWeaver classWeaver, MethodDefinition method, string name, MethodDefinition staticConstructor) : base(classWeaver, method, name, staticConstructor)
 {
 }