Example #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));
        }
Example #2
0
        /// <summary>
        /// 获取缓冲池的类型。
        /// </summary>
        /// <typeparam name="TKey">缓冲对象的键的类型。</typeparam>
        /// <typeparam name="TValue">缓冲对象的类型。</typeparam>
        /// <param name="element">缓冲池的配置元素。</param>
        /// <returns>缓冲池的类型。</returns>
        private static Type GetCacheType <TKey, TValue>(CacheElement element)
        {
            string typeName = element.CacheType;

            // 读取缓冲池类型,类型总是开放泛型类型。
            if (typeName.IndexOf(',') == -1)
            {
                // 如果不是类型的限定名 AssemblyQualifiedName,
                // 则尝试自动补全类型名称最后的 `2。
                if (!typeName.EndsWith("`2", StringComparison.Ordinal))
                {
                    typeName += "`2";
                }
            }
            Type cacheType = Type.GetType(typeName, false, true);

            if (cacheType == null)
            {
                throw CommonExceptions.InvalidCacheType(element);
            }
            // 构造闭合泛型类型。
            try
            {
                cacheType = cacheType.MakeGenericType(typeof(TKey), typeof(TValue));
            }
            catch (ArgumentException ex)
            {
                // 闭合泛型类型构造失败。
                throw CommonExceptions.InvalidCacheType(element, ex);
            }
            // 缓冲池类型不是 ICache{TKey, TValue}。
            if (!typeof(ICache <TKey, TValue>).IsAssignableFrom(cacheType))
            {
                throw CommonExceptions.InvalidCacheType_ICache(element);
            }
            return(cacheType);
        }
Example #3
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)));
        }