Beispiel #1
0
        /// <summary>
        /// 返回与指定的键关联的缓冲池。
        /// </summary>
        /// <typeparam name="TKey">缓冲对象的键的类型。</typeparam>
        /// <typeparam name="TValue">缓冲对象的类型。</typeparam>
        /// <param name="key">要获取的缓冲池的键。</param>
        /// <returns>与指定的键关联的缓冲池,如果未能找到则返回 <c>null</c>。</returns>
        private static ICache <TKey, TValue> CreateInternal <TKey, TValue>(string key)
        {
            Contract.Requires(key != null);
            // 读取配置文件。
            CacheSection section = ConfigurationManager.GetSection(SectionName) as CacheSection;

            if (section == null)
            {
                return(null);
            }
            CacheElement element = section.Caches[key];

            if (element == null)
            {
                return(null);
            }
            Type cacheType = GetCacheType <TKey, TValue>(element);
            // 读取缓冲池设置。
            Dictionary <string, string> options = new Dictionary <string, string>(element.Options.Count,
                                                                                  StringComparer.OrdinalIgnoreCase);

            foreach (NameValueConfigurationElement nv in element.Options)
            {
                options.Add(nv.Name, nv.Value);
            }
            return(CreateCacheType(cacheType, options) as ICache <TKey, TValue> ?? RaiseCacheResolve <TKey, TValue>(key, null));
        }
Beispiel #2
0
        /// <summary>
        /// 返回与指定的键关联的缓冲池。如果配置信息不存在,则返回 <c>null</c>。
        /// 如果配置文件出现错误,同样返回 <c>null</c>,这时候会发生 <see cref="CacheResolve"/> 事件。
        /// </summary>
        /// <typeparam name="TKey">缓冲对象的键的类型。</typeparam>
        /// <typeparam name="TValue">缓冲对象的类型。</typeparam>
        /// <param name="key">要获取的缓冲池的键。</param>
        /// <returns>与指定的键关联的缓冲池。如果配置不存在或非法,则返回 <c>null</c>。</returns>
        /// <exception cref="System.Configuration.ConfigurationErrorsException">配置文件错误。</exception>
        public static ICache <TKey, TValue> Create <TKey, TValue>(string key)
        {
            // 读取配置文件。
            CacheSection section = null;

            try
            {
                section = ConfigurationManager.GetSection(SectionName) as CacheSection;
            }
            catch (ConfigurationErrorsException ex)
            {
                return(OnCacheResolve <TKey, TValue>(key, ex));
            }
            if (section == null)
            {
                return(OnCacheDefault <TKey, TValue>(key));
            }
            CacheElement element = section.Caches[key];

            if (element == null)
            {
                return(OnCacheDefault <TKey, TValue>(key));
            }
            // 读取缓冲池类型。
            Type cacheType = null;

            try
            {
                cacheType = GetCacheType <TKey, TValue>(element);
            }
            catch (ConfigurationErrorsException ex)
            {
                return(OnCacheResolve <TKey, TValue>(key, ex));
            }
            // 读取缓冲池设置。
            int cnt = element.Options.Count;
            Dictionary <string, NameValueConfigurationElement> options =
                new Dictionary <string, NameValueConfigurationElement>(cnt, StringComparer.OrdinalIgnoreCase);

            foreach (NameValueConfigurationElement nv in element.Options)
            {
                options.Add(nv.Name, nv);
            }
            // 使用反射检索缓冲池类型,这里不能直接用 PowerBinder,是因为参数类型是未知的。
            // 找到与设置个数和名称匹配的构造函数。
            ConstructorInfo[] ctors  = cacheType.GetConstructors();
            object[]          values = new object[cnt];
            for (int i = 0; i < ctors.Length; i++)
            {
                ParameterInfo[] parameters = ctors[i].GetParameters();
                if (parameters.Length != cnt)
                {
                    continue;
                }
                // 测试参数名称是否全部能匹配上,并进行参数类型转换。
                int j = 0;
                for (; j < cnt; j++)
                {
                    NameValueConfigurationElement value;
                    if (!options.TryGetValue(parameters[j].Name, out value))
                    {
                        break;
                    }
                    // 尝试进行类型转换。
                    try
                    {
                        values[j] = Convert.ChangeType(value.Value,
                                                       parameters[j].ParameterType);
                    }
                    catch (InvalidCastException)
                    {
                        break;
                    }
                    catch (FormatException)
                    {
                        break;
                    }
                    catch (OverflowException)
                    {
                        break;
                    }
                }
                if (j < cnt)
                {
                    continue;
                }
                // 找到了匹配的构造函数,构造实例。
                try
                {
                    return(ctors[i].Invoke(values) as ICache <TKey, TValue>);
                }
                catch (MemberAccessException) { }
                catch (TargetInvocationException) { }
                catch (SecurityException) { }
            }
            return(OnCacheResolve <TKey, TValue>(key, CommonExceptions.InvalidCacheOptions(element)));
        }