예제 #1
0
        /// <summary>
        /// Invokes proxy methods which return a value.
        /// </summary>
        /// <typeparam name="T">The return type of the method being invoked.</typeparam>
        /// <param name="args">The arguments to pass to the method.</param>
        /// <returns>The return value of the default proxy method.</returns>
        /// <remarks>This method will invoke methods on all of the proxy objects, but will return
        /// the result of the invocation on the default object.
        /// </remarks>
        protected T ProxyInvoke <T>(params object[] args)
        {
            if (objects.Count == 0)
            {
                return(default(T));
            }

            StackTrace trace  = new StackTrace();
            StackFrame frame  = trace.GetFrame(1);
            MethodInfo method = frame.GetMethod() as MethodInfo;
            ProxyAttributeCollection attributes = GetAttributes(method);

            bool first  = true;
            T    result = default(T);

            foreach (object invoke in objects)
            {
                ProxyTypeBindingAttribute binding  = attributes.GetTypeBinding(invoke);
                MemberInfoAccessor        accessor = binding.GetTargetAccessor(typeof(T), args);
                if (first)
                {
                    result = (T)accessor.Get(invoke, args);
                    first  = false;
                }
                else
                {
                    accessor.Get(invoke, args);
                }
            }

            return(result);
        }
예제 #2
0
        /// <summary>
        /// Gets the <see cref="ProxyAttributeCollection"/> for a given <see cref="MethodInfo"/>.
        /// </summary>
        /// <param name="method">The method to get the proxy attributes for.</param>
        /// <returns>The collection of attributes for the given method as
        /// revealed by reflection of the method's attributes.
        /// </returns>
        private ProxyAttributeCollection GetAttributes(MethodInfo method)
        {
            if (!attributes.ContainsKey(method))
            {
                ProxyAttributeCollection collection = ReflectMethod(method);
                attributes.Add(method, collection);
            }

            return(attributes[method]);
        }
예제 #3
0
        /// <summary>
        /// Performs the get operation on the first object in the list of proxy objects (the default object).
        /// </summary>
        /// <typeparam name="T">The type to cast the return value as.</typeparam>
        /// <param name="args">The indices to pass to the get method.</param>
        /// <returns>The result of executing a get operation on the default proxy object, or the default value of T
        /// if there are no proxy objects.
        /// </returns>
        public T ProxyGet <T>(params object[] args)
        {
            if (objects.Count == 0)
            {
                return(default(T));
            }

            StackTrace trace  = new StackTrace();
            StackFrame frame  = trace.GetFrame(1);
            MethodInfo method = frame.GetMethod() as MethodInfo;
            ProxyAttributeCollection  attributes = GetAttributes(method);
            ProxyTypeBindingAttribute binding    = attributes.GetTypeBinding(objects[0]);
            MemberInfoAccessor        accessor   = binding.GetTargetAccessor(typeof(T), args);

            return((T)accessor.Get(objects[0], args));
        }
예제 #4
0
        /// <summary>
        /// Invokes proxy methods which do not return a value.
        /// </summary>
        /// <param name="args">The arguments to pass to the method.</param>
        protected void ProxyInvoke(params object[] args)
        {
            if (objects.Count == 0)
            {
                return;
            }

            StackTrace trace  = new StackTrace();
            StackFrame frame  = trace.GetFrame(1);
            MethodInfo method = frame.GetMethod() as MethodInfo;
            ProxyAttributeCollection attributes = GetAttributes(method);

            foreach (object invoke in objects)
            {
                ProxyTypeBindingAttribute binding  = attributes.GetTypeBinding(invoke);
                MemberInfoAccessor        accessor = binding.GetTargetAccessor(typeof(void), args);
                accessor.Get(invoke, args);
            }
        }
예제 #5
0
        /// <summary>
        /// Performs the set operation on all proxy objects.
        /// </summary>
        /// <param name="value">The value to set on the proxy objects.</param>
        /// <param name="args">The indices of the set operation.</param>
        protected void ProxySet(object value, params object[] args)
        {
            if (objects.Count == 0)
            {
                return;
            }

            StackTrace trace  = new StackTrace();
            StackFrame frame  = trace.GetFrame(1);
            MethodInfo method = frame.GetMethod() as MethodInfo;
            ProxyAttributeCollection attributes = GetAttributes(method);

            foreach (object invoke in objects)
            {
                ProxyTypeBindingAttribute binding = attributes.GetTypeBinding(invoke);
                object[] argsWithValue            = new object[args.Length + 1];
                argsWithValue[0] = value;
                Array.Copy(args, 0, argsWithValue, 1, args.Length);

                MemberInfoAccessor accessor = binding.GetTargetAccessor(typeof(void), argsWithValue);
                accessor.Set(invoke, value, args);
            }
        }
예제 #6
0
        /// <summary>
        /// Performs reflection on a method in order to determine which methods on proxy objects
        /// the method stub is bound to.
        /// </summary>
        /// <param name="method">The method to reflect over.</param>
        /// <returns>The collection of attributes about the method.</returns>
        private ProxyAttributeCollection ReflectMethod(MethodInfo method)
        {
            ProxyAttributeCollection collection = new ProxyAttributeCollection(method);

            // get the information that is applied directly to the method
            object[] typeBindings = method.GetCustomAttributes(typeof(ProxyTypeBindingAttribute), true);
            foreach (ProxyTypeBindingAttribute attribute in typeBindings)
            {
                collection.AddTypeBinding(attribute);
            }

            // if the method is a get or set method on a property, also get the attributes applied to the property
            if (MemberInfoAccessor.IsGetMethod(method) || MemberInfoAccessor.IsSetMethod(method))
            {
                PropertyInfo propertyInfo = MemberInfoAccessor.GetProperty(method);
                object[]     moreBindings = propertyInfo.GetCustomAttributes(typeof(ProxyTypeBindingAttribute), true);
                foreach (ProxyTypeBindingAttribute attribute in moreBindings)
                {
                    collection.AddTypeBinding(attribute);
                }
            }

            return(collection);
        }