zoukankan      html  css  js  c++  java
  • 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也是这么实现的。

  • 相关阅读:
    分布式环境下限流方案的实现redis RateLimiter Guava,Token Bucket, Leaky Bucket
    将bloomfilter(布隆过滤器)集成到scrapy-redis中
    Redis Cluster 分区实现原理
    OEM status|start|stop
    oracle 11g SQL Developer instead of isqlplus
    oracle Instance status: READY–lsnrctl status|start|stop
    oracle tns in linux
    Oracle 多实例如何通过EM进行访问-portlist.ini
    oracle command
    oracle .bash_profile
  • 原文地址:https://www.cnblogs.com/_dragon/p/1734165.html
Copyright © 2011-2022 走看看