private static DistributeCacheProvider InstantiateProvider(ProviderSettings providerSettings, CacheSettings cacheSettings) { DistributeCacheProvider provider = null; try { if (providerSettings == null) { throw new ArgumentNullException("providerSettings"); } string providerSettingTypeName = providerSettings.Type == null ? null : providerSettings.Type.Trim(); if (string.IsNullOrEmpty(providerSettingTypeName)) { throw new ArgumentException(String.Format("名称为 {0} 的分布式缓存提供程序缺少类型定义。", providerSettings.Name), "providerSettings"); } Type providerSettingType = Type.GetType(providerSettingTypeName, true, true); if (!typeof(DistributeCacheProvider).IsAssignableFrom(providerSettingType)) { throw new ArgumentException(String.Format("分布式缓存提供程序 {0} 必须实现或继承 {1}。", providerSettings.Name, typeof(DistributeCacheProvider).ToString())); } provider = (DistributeCacheProvider)Activator.CreateInstance(providerSettingType, providerSettings.CurrentConfiguration); provider.cacheSettings = cacheSettings; NameValueCollection parameters = providerSettings.Parameters; NameValueCollection config = new NameValueCollection(parameters.Count, StringComparer.Ordinal); foreach (string s in parameters) { config[s] = parameters[s]; } provider.Initialize(providerSettings.Name, config); } catch (Exception exception) { if (exception is ConfigurationException) { throw; } throw new ConfigurationErrorsException(exception.Message, exception, providerSettings.ElementInformation.Properties["type"].Source, providerSettings.ElementInformation.Properties["type"].LineNumber); } return provider; }
private void configService_ConfigFileChanged(object sender, ConfigFileChangedEventArgs e) { if (e.ConfigFileType == ConfigFileType.Cache) { CacheSettings oldSettings = instance; // 临时保存当前正确的实例 // 在配置文件变化时, 结合 CacheSettings.Instance 单例模式,通过将实例对象设置为 null,暂时阻止对单例实例的访问 lock (syncForSettings) { instance = null; // 将 instance 设置为 null,暂时阻止对单例实例的访问 CacheSettings newSettings = null; try { newSettings = new CacheSettings(); instance = newSettings; // 启用新的配置 } catch (Exception err) { instance = oldSettings; // 恢复为最近一次正确的配置 XMS.Core.Container.LogService.Warn("在响应配置文件变化的过程中发生错误,仍将使用距变化发生时最近一次正确的配置。", Logging.LogCategory.Configuration, err); } // 成功应用新的配置后,处理配置文件变化监听事件 if (instance != oldSettings) { if (oldSettings != null)// 为旧实例移除配置变化监听事件 { // 这里不能通过 Dispose 释放事件,因为 oldSettings 的实例有可能被在缓存相关操作方法里通过局部变量引用,后面仍然有可能继续使用 // 因此这里手动释放旧实例的监听事件 oldSettings.ConfigService.ConfigFileChanged -= oldSettings.configFileChangedEventHandler; } } } // 单例实例发生变化后,在 lock (syncForSettings) 语句之外清空缓存,以避免与 Clear 过程中发生死锁(因为锁定过程中会访问 CacheSettings 的单例实例) if (instance != oldSettings) { LocalCacheManager.Instance.Clear(); } } }
private static void InstantiateProviders(ProviderSettingsCollection configProviders, ProviderCollection providers, CacheSettings cacheSettings) { foreach (ProviderSettings settings in configProviders) { providers.Add(InstantiateProvider(settings, cacheSettings)); } }