代码改变世界

BlogEngine中的Provider模式(上)

2010-10-23 20:27  MichaelYin  阅读(482)  评论(0编辑  收藏  举报

BlogEngine中的数据存储部分使用了Provider模式来支持多种数据存储方式,比如Sql server,XML等。只需要通过修改Web.Config文件中的响应配置节就可以按需求进行数据存储方式的改变。

<configSections>
    <sectionGroup name="BlogEngine">
        <section name="blogProvider" requirePermission="false" type="BlogEngine.Core.Providers.BlogProviderSection, BlogEngine.Core" allowDefinition="MachineToApplication" restartOnExternalChanges="true"/>
    </sectionGroup>
</configSections>

首先在Web.Config中定义BlogEngine这个自定义节点,sectionGroup这个是存放section元素的容器,它不是必须要写的。section则是将配置节中的配置信息和配置处理程序提供关联。这里我们可以看到,它将blogProvider这个配置节和BlogProviderSection这个类提供了关联,name = “blogProvider”说明配置节为blogProvider

  public class BlogProviderSection : ConfigurationSection
  {

    /// <summary>
    /// A collection of registered providers.
    /// </summary>
    [ConfigurationProperty("providers")]
    public ProviderSettingsCollection Providers
    {
      get { return (ProviderSettingsCollection)base["providers"]; }
    }

    /// <summary>
    /// The name of the default provider
    /// </summary>
    [StringValidator(MinLength = 1)]
    [ConfigurationProperty("defaultProvider", DefaultValue = "XmlBlogProvider")]
    public string DefaultProvider
    {
      get { return (string)base["defaultProvider"]; }
      set { base["defaultProvider"] = value; }
    }

  }

上面是BlogProviderSection 的代码,用ConfigurationProperty Attribute标注的属性,系统在运行时从Web.Config中反序列化来实例化当前类。还需要注意的一个类是ProviderSettingsCollection

在configSections下面定义好了之后,就可以在Web.Config中用BlogEngine这个自定义节点来配置一些数据了.

<BlogEngine>
    <blogProvider defaultProvider="DbBlogProvider">
        <providers>
            <add name="XmlBlogProvider" type="BlogEngine.Core.Providers.XmlBlogProvider, BlogEngine.Core"/>
            <add name="DbBlogProvider" type="BlogEngine.Core.Providers.DbBlogProvider, BlogEngine.Core" connectionStringName="BlogEngine"/>
        </providers>
    </blogProvider>
</BlogEngine>

需要的配置信息都已经在Web.Config里面写好了,系统在运行的时候需要从Web.Config文件中动态读取配置信息,下面给出读取配置信息的代码

		private static void LoadProviders()
		{
			// Avoid claiming lock if providers are already loaded
			if (_provider == null)
			{
				lock (_lock)
				{
					// Do this again to make sure _provider is still null
					if (_provider == null)
					{
						// Get a reference to the <blogProvider> section
						BlogProviderSection section = (BlogProviderSection)WebConfigurationManager.GetSection("BlogEngine/blogProvider");

						// Load registered providers and point _provider
						// to the default provider
						_providers = new BlogProviderCollection();
						ProvidersHelper.InstantiateProviders(section.Providers, _providers, typeof(BlogProvider));
						_provider = _providers[section.DefaultProvider];

						if (_provider == null)
							throw new ProviderException("Unable to load default BlogProvider");
					}
				}
			}
		}

_provider为静态变量,多线程下先Double Check确保线程安全,然后用GetSection方法获取BlogProviderSection 的一个实例对象,然后ProvidersHelper.InstantiateProviders将ProviderSettingsCollection 类型的section.Providers初始化为一个BlogProvider集合类,最后从集合类中取出当前系统使用的provider.这样从配置文件中读取provider配置信息的过程基本就到此结束了

关于自定义配置园子里有相关文章,在这里给几个链接,我自己也从中收获颇丰,再次表示感谢。

Web.config自定义节点configSections

通过继承ConfigurationSection,在web.config中增加自定义配置