Exemplo n.º 1
0
        /// <summary>
        /// Creates a proxy for this object
        /// </summary>
        /// <typeparam name="I">Interface to proxy</typeparam>
        /// <typeparam name="A">Will only proxy method that have this attribute</typeparam>
        /// <param name="objectToProxy"></param>
        /// <param name="interceptorDelegate">delegate to call on method invocation</param>
        /// <returns></returns>
        public static I Proxy <I, A>(this I objectToProxy, EmitProxyInterceptor <I> interceptorDelegate) where A : Attribute
        {
            return(Proxy <I>(objectToProxy, (info) =>
            {
                //Check if hte attribute is on the interface
                //also check if our method info is actually a property value, if so we will check if the
                //attribute is on the property
                bool isAttributeOnInterface = typeof(I).GetMethod(info.Name, info.GetParameters().Select(p => p.ParameterType).ToArray()) != null;

                if (isAttributeOnInterface == false && info.IsSpecialName && (info.Name.StartsWith("get_") || info.Name.StartsWith("set_")))
                {
                    isAttributeOnInterface = typeof(I).GetProperty(info.Name.Remove(0, 4)) != null;
                }


                //Check if hte attribute is on our actual object
                //also check if our method info is actually a property value, if so we will check if the
                //attribute is on the property
                bool isAttributeOnMethod = info.GetCustomAttributes(typeof(A), true).Count() > 0;

                if (isAttributeOnMethod == false && info.IsSpecialName && (info.Name.StartsWith("get_") || info.Name.StartsWith("set_")))
                {
                    isAttributeOnMethod = objectToProxy.GetType().GetProperty(info.Name.Remove(0, 4)) != null;
                }



                //we have the attribute if it is either on the interface or method
                return isAttributeOnInterface || isAttributeOnMethod;
            }, interceptorDelegate));
        }
Exemplo n.º 2
0
 /// <summary>
 /// Creates a proxy for this object
 /// </summary>
 /// <typeparam name="I">Interface to proxy</typeparam>
 /// <param name="objectToProxy"></param>
 /// <param name="interceptorDelegate">delegate to call on method invocation</param>
 /// <returns></returns>
 public static I Proxy <I>(this I objectToProxy, EmitProxyInterceptor <I> interceptorDelegate)
 {
     return(Proxy <I>(objectToProxy, (info) => true, interceptorDelegate));
 }
Exemplo n.º 3
0
        /// <summary>
        /// Creates a proxy for this object
        /// </summary>
        /// <typeparam name="I">Interface to proxy</typeparam>
        /// <param name="objectToProxy"></param>
        /// <param name="methodSelector">predicate to select which methods call the <paramref name="interceptorDelegate"/> </param>
        /// <param name="interceptorDelegate">delegate to call on method invocation</param>
        /// <returns></returns>
        public static I Proxy <I>(this I objectToProxy, Predicate <MethodInfo> methodSelector, EmitProxyInterceptor <I> interceptorDelegate)
        {
            if (!typeof(I).IsInterface)
            {
                throw new Exception("Generic parameter must be an interface");
            }

            //ensure we have something in our interface level cache
            if (!_dynamicTypeCache.ContainsKey(typeof(I)))
            {
                _dynamicTypeCache[typeof(I)] = new Dictionary <Predicate <MethodInfo>, Type>();
            }

            //Check if the type is cached first, if not we go and emit a proxy class for the given interface
            //and pass null for the attribute we are proxying
            if (!_dynamicTypeCache[typeof(I)].ContainsKey(methodSelector))
            {
                _dynamicTypeCache[typeof(I)][methodSelector] = CreateProxy <I>(objectToProxy, methodSelector, interceptorDelegate);
            }



            return((I)Activator.CreateInstance(_dynamicTypeCache[typeof(I)][methodSelector], objectToProxy, interceptorDelegate));
        }
Exemplo n.º 4
0
        /// <summary>
        /// Creates a proxy
        /// </summary>
        /// <typeparam name="I">Interface of the proxy</typeparam>
        /// <param name="objectToProxy">object that is being proxied</param>
        /// <param name="interceptorDelegate">delegate to call on invocation</param>
        /// <param name="methodSelector">predicate to select which methods call the <paramref name="interceptorDelegate"/> </param>
        /// <returns>The proxy</returns>
        private static Type CreateProxy <I>(I objectToProxy, Predicate <MethodInfo> methodSelector, EmitProxyInterceptor <I> interceptorDelegate)
        {
            //create the dynamic assembly
            ModuleBuilder moduleBuilder = CreateAssembly(ASSEMBLY_NAME, MODULE_NAME);

            //create our new type that implements the proxy interface
            TypeBuilder typeBuilder = moduleBuilder.CreateType <I, object>(typeof(I).Name + TYPE_SUFFIX);

            //copy the class custom attributes
            foreach (CustomAttributeBuilder attrBuilder in CreateCustomAttributeBuilder(objectToProxy.GetType()))
            {
                typeBuilder.SetCustomAttribute(attrBuilder);
            }



            //create two fields, one to store the proxied object, and one to store the Interceptor delegate
            //this will also create a constructor to set both these values
            FieldInfo[] fieldInfo = typeBuilder.CreateFieldsAndConstrucutor(
                typeof(I), "ProxiedObject",
                typeof(EmitProxyInterceptor <I>), "Interceptor");

            //Create an implementation of each method in the interface. There is a direct implementation
            //to conform to the interface, and an execute method that will call the proxied object directly
            //given an object and a parameter list
            foreach (MethodInfo interfaceMethodInfo in typeof(I).GetAllInterfaceMethods())
            {
                //get a list of parameter types
                ParameterInfo[] parameterInfos = interfaceMethodInfo.GetParameters();
                Type[]          parameterTypes = new Type[parameterInfos.Length];
                for (int i = 0; i < parameterInfos.Length; i++)
                {
                    parameterTypes[i] = parameterInfos[i].ParameterType;
                }

                //get the method info of the actual object, it might have the attributes we are looking
                MethodInfo proxiedMethodInfo = objectToProxy.GetType().GetMethod(interfaceMethodInfo.Name, parameterTypes);

                //will only create proxy to call delegate if it contains the attribute we are looking for
                //(note that either the itnerface or the actual object we are proxing can have the attribute)
                //or no attribute was defined
                MethodBuilder proxyMethod;
                if (methodSelector(proxiedMethodInfo))
                {
                    MethodInfo executeMethod = typeBuilder.CreateExecuteMethod <I>(EXECUTE_PREFIX + interfaceMethodInfo.Name, interfaceMethodInfo);
                    proxyMethod = typeBuilder.CreateProxyMethod <I>(interfaceMethodInfo, executeMethod, fieldInfo[0], fieldInfo[1]);
                }
                else
                {
                    proxyMethod = typeBuilder.CreatePassThroughMethod <I>(interfaceMethodInfo, fieldInfo[0]);
                }

                //Copy accross the attributes
                foreach (CustomAttributeBuilder attrBuilder in CreateCustomAttributeBuilder(proxiedMethodInfo))
                {
                    proxyMethod.SetCustomAttribute(attrBuilder);
                }
            }

            return(typeBuilder.CreateType());
        }
 /// <summary>
 /// Creates a proxy for this object
 /// </summary>
 /// <typeparam name="I">Interface to proxy</typeparam>
 /// <param name="objectToProxy"></param>
 /// <param name="interceptorDelegate">delegate to call on method invocation</param>
 /// <returns></returns>
 public static I Proxy <I>(this I objectToProxy, EmitProxyInterceptor <I> interceptorDelegate)
 {
     return(PlatformTypeProxyCsharpHelper.Proxy <I>(objectToProxy, (info) => true, interceptorDelegate));
 }