示例#1
0
            /// <summary>
            /// 使用处理器的委托列表初始化 <see cref="ProcessorData"/> 类的新实例。
            /// </summary>
            /// <param name="delegates">使用不同子类作为参数的委托列表。</param>
            /// <exception cref="ArgumentException">处理器的参数不匹配。</exception>
            /// <exception cref="ArgumentException">没有找到唯一的关键参数。</exception>
            public ProcessorData(Delegate[] delegates)
            {
                Contract.Requires(delegates != null && delegates.All(d => d != null));
                this.IsStatic = true;
                List <MethodInfo> list = new List <MethodInfo>(delegates.Length);

                list.AddRange(delegates.Select(d => d.GetInvokeMethod()));
                int cnt = list.Count;
                // 发现关键参数,所有处理器各不相同的参数就认为是关键参数。
                List <Type[]> paramTypes = new List <Type[]>(cnt);

                for (int i = 0; i < cnt; i++)
                {
                    paramTypes.Add(list[i].GetParameterTypesWithReturn());
                }
                this.KeyIndex = FindKeyIndex(null, null, paramTypes);
                // 构造委托类型。
                this.DelegateParamTypes = FindDelegateType(paramTypes, null);
                this.DelegateType       = Expression.GetDelegateType(this.DelegateParamTypes);
                this.Processors         = new Dictionary <Type, Delegate>(cnt);
                for (int i = 0; i < cnt; i++)
                {
                    Type keyType = list[i].GetParameters()[this.KeyIndex].ParameterType;
                    // 经过前面的类型检查,包装委托时应当总是会成功。
                    this.Processors.Add(keyType, DelegateBuilder.Wrap(this.DelegateType, delegates[i]));
                }
            }
示例#2
0
            /// <summary>
            /// 使用处理器所属的类型和标识初始化 <see cref="ProcessorData"/> 类的新实例。
            /// </summary>
            /// <param name="type">处理器所属的类型。</param>
            /// <param name="id">处理器的标识。</param>
            /// <exception cref="ArgumentException">没有找到处理器。</exception>
            /// <exception cref="ArgumentException">处理器中混杂着静态和动态方法。</exception>
            /// <exception cref="ArgumentException">处理器的参数不匹配。</exception>
            /// <exception cref="ArgumentException">没有找到唯一的关键参数。</exception>
            public ProcessorData(Type type, string id)
            {
                Contract.Requires(type != null && id != null);
                // 寻找处理器。
                MethodInfo[]      methods = type.GetMethods(TypeExt.AllMemberFlag);
                List <MethodInfo> list    = new List <MethodInfo>(methods.Length);

                list.AddRange(methods.Where(m => m.GetCustomAttributes(typeof(ProcessorAttribute), true)
                                            .Cast <ProcessorAttribute>().Any(p => p.Id == id)));
                int cnt = list.Count;

                if (cnt == 0)
                {
                    throw CommonExceptions.ProcessorNotFound(type, id);
                }
                // 判断是静态方法还是动态方法。
                this.IsStatic = list[0].IsStatic;
                if (list.Any(m => m.IsStatic != IsStatic))
                {
                    throw CommonExceptions.ProcessorMixed(type, id);
                }
                // 发现关键参数,所有处理器各不相同的参数就认为是关键参数。
                List <Type[]> paramTypes = new List <Type[]>(cnt);

                for (int i = 0; i < cnt; i++)
                {
                    paramTypes.Add(list[i].GetParameterTypesWithReturn());
                }
                this.KeyIndex = FindKeyIndex(type, id, paramTypes);
                // 构造委托类型。
                this.DelegateParamTypes = FindDelegateType(paramTypes, this.IsStatic ? null : type);
                this.DelegateType       = Expression.GetDelegateType(this.DelegateParamTypes);
                this.Processors         = new Dictionary <Type, Delegate>(cnt);
                for (int i = 0; i < cnt; i++)
                {
                    Type keyType = list[i].GetParameters()[this.KeyIndex].ParameterType;
                    // 经过前面的类型检查,创建委托时应当总是会成功。
                    this.Processors.Add(keyType, DelegateBuilder.CreateDelegate(this.DelegateType, list[i]));
                }
            }
示例#3
0
        /// <summary>
        /// 返回与指定标识符相关的处理器方法集合。
        /// </summary>
        /// <typeparam name="TDelegate">使用基类型调用方法的委托。</typeparam>
        /// <param name="type">在其中查找静态或实例方法的类型。</param>
        /// <param name="id">方法切换器的标识符。</param>
        /// <param name="index">方法的关键参数索引。</param>
        /// <param name="queryStatic">是否请求的是静态方法。</param>
        /// <returns>与指定标识符相关的处理器方法集合。</returns>
        private static Dictionary <Type, Delegate> GetMethods <TDelegate>(Type type, string id, int index, bool queryStatic)
        {
            Type dlgType = typeof(TDelegate);
            Tuple <bool, Type, Dictionary <Type, Delegate> > data;
            string key = string.Concat(type.FullName, "_", id);

            if (!methodDict.TryGetValue(key, out data))
            {
                MethodInfo[]      methods = type.GetMethods(MethodFlags);
                List <MethodInfo> list    = new List <MethodInfo>();
                for (int i = 0; i < methods.Length; i++)
                {
                    if (methods[i].GetCustomAttributes(typeof(ProcessorAttribute), true)
                        .Cast <ProcessorAttribute>().Any(s => s.Id == id))
                    {
                        list.Add(methods[i]);
                    }
                }
                int cnt = list.Count;
                if (cnt == 0)
                {
                    throw ExceptionHelper.ProcessorNotFound("type", type, id);
                }
                bool isStatic = list[0].IsStatic;
                for (int i = 1; i < cnt; i++)
                {
                    if (list[i].IsStatic != isStatic)
                    {
                        throw ExceptionHelper.ProcessorMixed("type", type, id);
                    }
                }
                Dictionary <Type, Delegate> dict = new Dictionary <Type, Delegate>();
                Type newDlgType = dlgType;
                if (!isStatic)
                {
                    newDlgType = GetInstanceDlgType(newDlgType);
                }
                for (int i = 0; i < cnt; i++)
                {
                    Type     keyType = list[i].GetParameters()[index].ParameterType;
                    Delegate dlg     = DelegateBuilder.CreateDelegate(newDlgType, list[i], false);
                    if (dlg == null)
                    {
                        throw ExceptionHelper.DelegateCompatible(list[i].ToString(), dlgType);
                    }
                    dict.Add(keyType, dlg);
                }
                data = new Tuple <bool, Type, Dictionary <Type, Delegate> >(isStatic, dlgType, dict);
                methodDict.Add(key, data);
            }
            if (data.Item1 != queryStatic)
            {
                throw ExceptionHelper.ProcessorMismatch("type", type, id);
            }
            if (data.Item2 != dlgType)
            {
                // 检查委托参数。
                ParameterInfo[] paramInfos    = data.Item2.GetMethod("Invoke").GetParameters();
                ParameterInfo[] dlgParamInfos = dlgType.GetMethod("Invoke").GetParameters();
                if (paramInfos.Length != dlgParamInfos.Length)
                {
                    throw ExceptionHelper.DelegateCompatible("TDelegate", dlgType);
                }
                for (int i = 0; i < paramInfos.Length; i++)
                {
                    if (paramInfos[i].ParameterType != dlgParamInfos[i].ParameterType)
                    {
                        throw ExceptionHelper.DelegateCompatible("TDelegate", dlgType);
                    }
                }
            }
            return(data.Item3);
        }