BlogEngine.NET 1.5的BlogProvider、DbBlogProvider

 

(1)ProviderBase是个抽象类,这里主要关注其中的虚方法Initialize

(2)BlogProvider也是一个抽象类,继承自ProviderBase提供了自己的抽象方法,例如

public abstract Post SelectPost(Guid id);

public abstract void InsertPost(Post post);等等,

这些抽象方法的具体实现由BlogProvider类的派生类来实现,在这里拿DbBlogProvider类来讨论(另外一个是XmlBlogProvider)。

3)DbBlogProvider类继承了BlogProvider类,实现了父类的抽象方法,用来实现增、删、查、改等等数据交互,DbBlogProvider类还重写了父类(BlogProvider)的父类(ProviderBase)的Initialize方法,大概是用来根据自定义的提供程序提取相应的信息,例如连接字符串等,这个自定义提供程序的选择,在BlogService类中的LoadProviders方法中进行。

(4BlogProviderSection类中定义了自定义的配置节点的相关信息。

(5) BlogProviderCollection类继承自ProviderCollection类,重写了Add方法,代码如下

BlogProviderCollection的Add方法
public override void Add(ProviderBase provider)
        {
            
if (provider == null)
                
throw new ArgumentNullException("provider");

            
if (!(provider is BlogProvider))
                
throw new ArgumentException
                    (
"Invalid provider type""provider");

            
base.Add(provider);
            
//为了看清楚base.Add(provider);,贴出ProviderCollection中的Add方法
            
//private Hashtable _Hashtable = new Hashtable(10, StringComparer.OrdinalIgnoreCase);
            
//public virtual void Add(ProviderBase provider)
            
//{
            
//    if (this._ReadOnly)
            
//    {
            
//        throw new NotSupportedException(SR.GetString("CollectionReadOnly"));
            
//    }
            
//    if (provider == null)
            
//    {
            
//        throw new ArgumentNullException("provider");
            
//    }
            
//    if ((provider.Name == null) || (provider.Name.Length < 1))
            
//    {
            
//        throw new ArgumentException(SR.GetString("Config_provider_name_null_or_empty"));
            
//    }
            
//    this._Hashtable.Add(provider.Name, provider);
            
//}

 

(6)BlogService类的 LoadProviders方法

BlogService类的 LoadProviders方法
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));
                        
        
//section.Providers是一个ProviderSettingsCollection类型,_providers是一个ProviderCollection类型
        
//ProvidersHelper.InstantiateProviders实际上通过_providers的Add方法调用了一个它的重载方法,这个方法中创建一个ProviderBase对象,
       
//调用ProviderBase对象的Initialize方法初始化提供程序,返回一个ProviderBase类型的对象
                        _provider = _providers[section.DefaultProvider];  
                 
// 根据索引返回一个[DbBlogProvider]的BlogProvider对象给_provider

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

 

LoadProviders方法中,先是通过自定义的配置节获取配置节点没,之后创建BlogProviderCollection对象,接着调用了ProvidersHelper.InstantiateProviders方法,该方法有2个重载,这里的ProvidersHelper.InstantiateProviders(section.Providers, _providers, typeof(BlogProvider));的具体实现如下:

ProvidersHelper.InstantiateProviders(section.Providers, _providers, typeof(BlogProvider))
 [AspNetHostingPermission(SecurityAction.Demand, Level=AspNetHostingPermissionLevel.Low)]
     
public static void InstantiateProviders(ProviderSettingsCollection configProviders, ProviderCollection providers, Type providerType)
    {
        
foreach (ProviderSettings settings in configProviders)
        {
            providers.Add(InstantiateProvider(settings, providerType));
         
// 在这里providers是BlogProviderCollection对象。

// InstantiateProvider(settings, providerType)是另一个重载方法,内部实现如下:
// [AspNetHostingPermission(SecurityAction.Demand, Level=AspNetHostingPermissionLevel.Low)]
    
//public static ProviderBase InstantiateProvider(ProviderSettings providerSettings, Type providerType)
    
//{
    
//    ProviderBase base2 = null;
    
//    try
    
//    {
    
//        string str = (providerSettings.Type == null) ? null : providerSettings.Type.Trim();
    
//        if (string.IsNullOrEmpty(str))
    
//        {
    
//            throw new ArgumentException(SR.GetString("Provider_no_type_name"));
    
//        }
    
//        Type c = ConfigUtil.GetType(str, "type", providerSettings, true, true);
    
//        if (!providerType.IsAssignableFrom(c))
    
//        {
    
//     throw new ArgumentException(SR.GetString("Provider_must_implement_type", new object[] { providerType.ToString() }));
    
//        }
//        base2 = (ProviderBase) HttpRuntime.CreatePublicInstance(c);
//   在这里通过HttpRuntime.CreatePublicInstance(c)动态创建指定类型的实例,
// HttpRuntime.CreatePublicInstance(c)其实就是调用了Activator.CreateInstance(type);
// 还有Assembly.CreateInstance()其实也是调用了Activator.CreateInstance(type);
    
//        NameValueCollection parameters = providerSettings.Parameters;
    
//        NameValueCollection config = new NameValueCollection(parameters.Count, StringComparer.Ordinal);
    
//        foreach (string str2 in parameters)
    
//        {
    
//            config[str2] = parameters[str2];
    
//        }
    
//        base2.Initialize(providerSettings.Name, config);
    
//    }
    
//    catch (Exception exception)
    
//    {
    
//        if (exception is ConfigurationException)
    
//        {
    
//            throw;
    
//        }
    
//        throw new ConfigurationErrorsException(exception.Message, providerSettings.ElementInformation.Properties["type"].Source, providerSettings.ElementInformation.Properties["type"].LineNumber);
    
//    }
//    return base2;
    
//}
        }
    }

 

 _provider = _providers[section.DefaultProvider]; ,因为之前已经通过方法ProvidersHelper.InstantiateProviders(section.Providers, _providers, typeof(BlogProvider));将所有的自定义提供程序的相关信息存储到Hashtable中,BlogProviderCollection类中有个索引

BlogProviderCollection的索引
public new BlogProvider this[string name]
        {
            
get { return (BlogProvider)base[name]; }
                
//base[name]的实现
                
//public ProviderBase this[string name]
                
//{
                
//    get
                
//    {
                
//        return (this._Hashtable[name] as ProviderBase);
                
//    }
                
//}
        }

_providers[section.DefaultProvider]根据自定义配置节中的默认的自定义提供程序获取动态创建的实例,不管是DbBlogProvider类或者是其他类,只要继承BlogProvider,只要提供了父类抽象类的实现,只要在web.config中的自定义节中进行了配置,就可以通过_provider.具体方法()来进行具体的操作,不需要去知道底层是用什么方式实现。大概MembershipProvider也是这么实现的。

posted @ 2010-05-13 02:48  ._  阅读(339)  评论(0编辑  收藏  举报