BlogEngine中的Provider模式(上)

Last updated on by michaelyin

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中增加自定义配置

Send Me Message

Tell me more about your project and see if I can help you.

Contact Me