分享CommunityServer(3) --Provider

原创 2007年10月03日 14:17:00

Provider实现 

Provider 是重配置轻编程的第二个体现。
我们都知道分层设计很重要,也知道在保持结构稳定的基础上,应当做到最大的灵活性,所谓具体环境的无关性。比如我们设计的时候可以通过分析,将一些功能进行抽象,并独立出来。比如,我们需要做到数据库无关,我们需要将全部数据访问设计到数据库部分进行独立设计,并通过分析提炼出相应的功能抽象,然后可以根据实际的数据库,设计相应的面向特定数据库的数据访问类,以便做到最终可以灵活通过配置文件,来切换不同的数据驱动。
Provider 的定义在 CSConfiguration.cs,该类只是一个存储Provider的实体类,用来描述具体的功能的Provider,从XMNode中分析出数据,主要有 Name(Provider的名称)、 ExtensionType(扩展类型)、Type(类型字符串),另外,还适应更多的设定,Provider还增加一个名Attributes的值对收集,通过键名可获取值。
CS中的Provider都是采用静态Instance方法来获取的,在名为instance的静态函数中进行从字符串到一个类实例的,这一切当然是得益于.net的反射功能。具体我们从一个实例来分析:
 
分析 CommonDataProvider.cs
。。。。。。
     #region Instance
        private static CommonDataProvider _defaultInstance = null;
        static CommonDataProvider()
        {
            CreateDefaultCommonProvider();//静态构造函数在第一次调用该类的任何静态方法前进行构造
        }
         ……
        private static void CreateDefaultCommonProvider()
        {  
            CSConfiguration config = CSConfiguration.GetConfig();//获得全局配置类,这个上一篇进行了分析           
            Provider sqlForumsProvider = (Provider) config.Providers[CommonDataProviderName];
//从provider集合中获取名为 “CommonDataProvider 的(CommonDataProviderName是private string类型的数据成员)provider ,注意 sqlForumsProvider 的类型是一个描述逻辑组件的实体信息类,并不是真正的提供功能的类。就好像产品说明书只是 描述产品的,而不是产品。这里的provider具体实例就是一个产品说明书,而下 _defaultInstance 才是真正的提供功能的产品
            _defaultInstance = DataProviders.CreateInstance(sqlForumsProvider) as CommonDataProvider; //通过读取provider(产品说明书)信息后进行反射 活动 来创建功能的实际实例。
        }       
        #endregion
。。。。。。
我们需要注意了 , CommonDataProvider 在此是一个抽象类 (public abstract class CommonDataProvider),必须通过具体的抽象,对于Data类型的provider,CS通过一个 sealed 类 DataProviders 来实现实例化 CreateInstance 细节如下:
     public static object CreateInstance(Provider dataProvider)
        {             
            string connectionString = null; //dataProvider.Attributes["connectionString"];
            string databaseOwner = null;// dataProvider.Attributes["databaseOwner"];
            GetDataStoreParameters(dataProvider, out connectionString, out databaseOwner);
            //Get the type
            Type type = Type.GetType(dataProvider.Type);     //通过反射获得类实例的Type
            object newObject = null;
            if(type != null)         //存在 Type
            {
                newObject = Activator.CreateInstance(type,new object[]{databaseOwner,connectionString}); //反射获取实例
            }           
            if(newObject == null) //If we can not create an instance, throw an exception
                ProviderException(dataProvider.Name);
 
            return newObject;
        }
基本上,Provider模式利用.net反射功能,实现通过.congfi中的xml节点描述就创建最终的实例,就是利用了反射的能力。对于其他provider配置节点中的组件 ,都是类似这类方法实现的。DataProviders有点 “将provider描述变成具体的功能组件实例”的工具。
通常,都在 CommunityServerComponents 工程中将需要的可以利用provider模式进行设定的功能,利用abstract 类进行描述功能,然后在其他工程(如数据访问provider单独成为一个工程)中实现这个抽象类的具体实例,但是会继承这类的instance能力。
全部Provider的功能设计在 CommunityServerComponents 的 Provider 目录,
 
ApplicationKeyProvider           提供将Url查询串等转换为应用程序键 ApplicationKey 的功能,如果需要改变ApplicationKey的映射规则,可覆盖改类,修改comuunityserv.config即可实现。
 
ChineseTokenizeProvider        提供中文分词的接口,其中的搜索需要进行分词,而分词有不少独立算法,可以通过Provider设定来置换专用算法。改类是一个抽象类,你要实现的方法其实仅有一个 public abstract string[] ChineseTokenize(string input); 也就是将输入字符串,通过分词算法返回字符串词数组
 
CommonDataProvider 上面基本上已经提供了分析,该类相当庞大,并且按照数据库表实体表大致进行了分组,基本上全部数据库对象操作都可以在此进行定义。通过继承该类可以实现具体的面向不同数据库的版本。如过实现了面向Access的版本,就应该从此类继承实现,并修改communityServer.config的相关provider配置节
 
EmailQueueProvider  提供对于Email队列操作的定义,分别有 QueueEmail DequeueEmail DeleteQueuedEmail 等操作需要覆盖实现。
 
EmailTemplateProvider 提供邮件模板处理功能的provider基类,主要定义的模板操作有GetTemplate,并提供基础的对于Email模板的功能,方便后类实现。GetTemplate就是要求将发送的email通过专用模板,进行模板操作后获得特定的邮件正文。
 
ExtensionModule 定义了对于CS的插件模板的定义,通过provider模式进行替换,比如,你要一个CMS模块,你只需要实现特定的方法 Init 和 ProcessRequest 方法就可实现插件替换。
 
SearchProvider 提供了对于系统内搜索的可替换功能的定义。
 
UrlReWriteProvider          提供对于Url重写的功能实现,后将专题介绍。
 
 
如果我们有需要对某个特定功能进行灵活性处理,该如何做?我们就针对分词provider进行分析吧。
 
首先,我们需要创建抽象类,定义provider的基本功能需求,如ChineseTokenizer.cs中定义了分词的功能,输入字符串,返回词组 public abstract string[] ChineseTokenize(string input);
然后,我们集成该类,实现其抽象类功能。具体,我们可以添加一个simpleChineseTOkenizer
public class ChineseTokenizer :ChineseTokenizeProvider
     {
         public ChineseTokenizer()
         {}
     #region ChineseTokenizeProvider 成员
              public override string[] ChineseTokenize(string input)
              {
                   try
                   {
                        someWordSeg.WordSeg dictSeg=new WordSeg();
                       return dictSeg.Segment(input);  //分词
                   }
                   catch(Exception )
                   {//出现例外
                   }
                   return input.Split("".ToCharArray());
              }
     #endregion
someWordSeg是一个分词的组件,实现中文分词。ChineseTokenizeProvider 的分词实际由此组件实际提供。
 
实现了具体的provider功能后(把具体的实现类放置在SearchBarrel工程中),我们需要登记provider,具体在communityserver.config中添加一个节点,我们取名为
 
                   <add
                    name=      "ChineseTokenizeProvider"
                    type="CommunityServer.Components.SearchBarrel. ChineseTokenizeProvider, CommunityServer.Components.SearchBarrel"/>
CommunityServer.Components.SearchBarrel. ChineseTokenizeProvider 是类名,CommunityServer.Components.SearchBarrel是程序集名。
 
这样,全局就可以知道存在这样一个分词组件,但是无需知道具体的实现,然后我们在需要分词功能的时候进行如下的步骤获取分词功能:
.
string[]  words = ChineseTokenizeProvider.Instance().ChineseTokenize(searchTerms);
instance 最终是按照如下逻辑进行实例化provider的:
。。。
CSConfiguration config = CSConfiguration.GetConfig();
         Provider chineseProviders = (Provider)config.Providers["ChineseTokenizeProvider"];
          _defaultInstance = Activator.CreateInstance(Type.GetType(chineseProviders.Type)) as ChineseTokenizeProvider;
。。。
简单总结就是:
1、 抽象出可按照provider设计的功能需求,设立一个抽象类,并在抽象基类定义instance函数,能够通过instance函数获得某个具体的provider实例,这就是做到所谓契约编程了。契约编程,不一定就要通过接口来实现。
2、 然后实现一个具体的实现类,实现具体的功能
3、 登记provider项目,在communityserver。Config中
4、 在需要provider的地方通过抽象类的instance方法实现具体组件的实例化,达到了组件化、定制化的组件协作。这样的设计会合理划分类边界,灵活性和实用性结合。也就是体现“重配置、轻编程”
 

FileProvider文件分享

最近在做一个文件分享的Demo,一连看了两天文档,终于把它给弄出来了。下面是文档中的一段话,大致的意思是通过FileProvider在应用程序之间共享文件的安全的。进程间文件的分享,假设两个应用程序分...
  • lin962792501
  • lin962792501
  • 2016年08月09日 17:34
  • 1063

ContentProvider数据库共享之——读写权限与数据监听

前言:随着工作的时间越来越长,越来越觉得自己学知识的速度太慢,原定的两年,现在已经过了快九个月了,仍然对很多知识懵懵懂懂,对JAVA理解的还是不够彻底,现在终于有点时间能放纵地看一些自己感兴趣的东西了...
  • harvic880925
  • harvic880925
  • 2015年03月26日 16:39
  • 12202

Android 7.0 行为变更 通过FileProvider在应用间共享文件吧

本文已在我的公众号hongyangAndroid原创首发。 转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/7285...
  • lmj623565791
  • lmj623565791
  • 2017年06月09日 09:03
  • 46221

Pro Android学习笔记(六六):安全和权限(3):Provider权限

访问其他应用的content provider 我们在ProPermission中提供了一个content provider,成为PrivProvider,然后在ProPermissionCli...
  • SQ_Bang
  • SQ_Bang
  • 2016年08月22日 20:06
  • 188

Initializing connection provider: org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider

 Initializing connection provider: org.springframework.orm.hibernate3.LocalDataSourceConnectionProvi...
  • zdwzzu2006
  • zdwzzu2006
  • 2011年06月07日 23:10
  • 11949

由浅入深写java分布式(3) dubbo admin监控dubbo 以及外网consumer找不到provider的问题

将dubbo-admin-2.8.4.war 放到tomcat的webapps中 启动解压后修改 D:\apache-tomcat-7.0.63\webapps\dubbo-admin-2.8.4\W...
  • kkgbn
  • kkgbn
  • 2017年02月17日 14:18
  • 1330

Android development Notes-3(Activity, Intents, and Tasks, Service, Content provider)

-Android introduces a richer and more complex approach by supporting multiple application entry poin...
  • yu444
  • yu444
  • 2016年02月26日 23:05
  • 1164

Android学习笔记(3)————Android四大组件之三(Content Provider)

1、Content Provider(内容提供者)简介          从字面上的意思来看,Content Providers是内容提供者,也就是数据的提供者,而数据的来源可以是SQLite数...
  • u010779977
  • u010779977
  • 2014年05月30日 14:09
  • 347

performance test - L3 Network VS Provider Network

After enable neutron-l3-agent, we want to know the network performance. I will compare neutron-l3-ag...
  • maoliping455mlp455
  • maoliping455mlp455
  • 2014年04月11日 10:53
  • 6394

分享Android 跨进程通讯的4种方式 [Activity][Content Provider][Broadcast][Service]

前言:最近忙于做第三方应用集成,关注了进程间通讯协议与方法,收集到以下教程,与大家分享,感谢原博主的无私奉献 来源:   http://www.2cto.com/kf/201202/119100.h...
  • huanghr_1
  • huanghr_1
  • 2012年08月30日 15:12
  • 2205
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:分享CommunityServer(3) --Provider
举报原因:
原因补充:

(最多只允许输入30个字)