• [CommunityServer]自定义扩展Provider的实现.


      自定义扩展Provider当然要有自己的配制文件,在上一编文章中我们介绍了文件CommunityServer.config,在CORE节点我们可找到<provider>节点,这个配制,今天我们来看看从读取到实现的整个过程.当然我们的程序可能只有个别Provider需要扩展就不需要自己配制一个文件,我们可以通过在Web.config文件中配制一个节点用来存储Provider或直接放在<appSettings>中.

      下面我们来看看provider的配制文件:
     
    PROVIDER

      从上面可以看到,provider主要包括两个配制,一个是name:用于搜索用的唯一provider名称;type:工作类的程序集和类,一定要按照"类,程序集"的顺序,不然会出错的哦,不信你试试!当然还有其它配制,在CS中可以将其它配制存在一个NameValueCollection中,这样就可以随便扩展而不要写他的实体类了,这也是值得我们学习的地方啊。

      知道了配置文件,我们可以从CSConfiguration.cs文件中找到Provider的实体类,通过CSConfiguration类将其读取并缓存,这样能提高效率。关于怎样读取,我想回用XML的人都懂得,这里就不多说了,下面来看看代码。
    ProviderEntity

      Nme就是上面所说的配置节点中的name属性;Type就是type属性,将其他的如ConnectionString等保存在Attributes中,我们可以通过key&value来读取。到这里我们已经读取了provider配置,但要实现provider还需要通过反射技术,在DataProviders可以看到,这个类主要用于数据库的扩展类,一些非数据库的类大多用SingletonProviderHelper来实现,原理都差不多,主要DataProviders通过查找最匹配的具有(string connectionString,string dataOwrer)来对其实例化,在CSlReWriter类中就可以看到用SingletonProviderHelper来对其虚函数进行实例化。

      1public sealed class DataProviders
      2    {
      3        /// <summary>
      4        /// This class can not be instantiated
      5        /// </summary>

      6        private DataProviders()
      7        {
      8        }

      9
     10        private static void GetDataStoreParameters(Provider dataProvider, out string connectionString, out string databaseOwner)
     11        {
     12            databaseOwner = dataProvider.Attributes["databaseOwner"];
     13            if(databaseOwner == null || databaseOwner.Trim().Length == 0)
     14                databaseOwner = ConfigurationSettings.AppSettings[dataProvider.Attributes["databaseOwnerStringName"]];
     15
     16            connectionString = dataProvider.Attributes["connectionString"];
     17            if(connectionString == null || connectionString.Trim().Length == 0)
     18                connectionString = ConfigurationSettings.AppSettings[dataProvider.Attributes["connectionStringName"]];
     19        }

     20
     21        /// <summary>
     22        /// Creates an instance of the provider using Activator. This instance should be
     23        /// cached since it is an expesivie operation
     24        /// </summary>

     25        public static object CreateInstance(Provider dataProvider)
     26        {
     27            //Find the current attributes
     28            string connectionString = null//dataProvider.Attributes["connectionString"];
     29            string databaseOwner = null;// dataProvider.Attributes["databaseOwner"];
     30
     31            GetDataStoreParameters(dataProvider, out connectionString, out databaseOwner);
     32
     33            //Get the type
     34            Type type  = Type.GetType(dataProvider.Type);
     35
     36            object newObject = null;
     37            if(type != null)
     38            {
     39                newObject =  Activator.CreateInstance(type,new object[]{databaseOwner,connectionString});  
     40            }

     41            
     42            if(newObject == null//If we can not create an instance, throw an exception
     43                ProviderException(dataProvider.Name);
     44
     45            return newObject;
     46        }

     47
     48        /// <summary>
     49        /// Creates and Caches the ConstructorInfo for the specified provider. 
     50        /// </summary>

     51        public static ConstructorInfo CreateConstructorInfo (Provider dataProvider) 
     52        {
     53
     54            // The assembly should be in \bin or GAC, so we simply need
     55            // to get an instance of the type
     56            //
     57            CSConfiguration config = CSConfiguration.GetConfig();
     58            ConstructorInfo providerCnstr = null;
     59            try 
     60            {
     61                //string providerTypeName = ((Provider) config.Providers[providerName]).Type;
     62                Type type  = Type.GetType( dataProvider.Type );
     63
     64                // Insert the type into the cache
     65                //
     66                Type[] paramTypes = new Type[2];
     67                paramTypes[0= typeof(string);
     68                paramTypes[1= typeof(string);
     69
     70                providerCnstr = type.GetConstructor(paramTypes);
     71
     72            }
     
     73            catch 
     74            {
     75                ProviderException(dataProvider.Name);
     76            }

     77
     78           if(providerCnstr == null)
     79               ProviderException(dataProvider.Name);
     80
     81            return providerCnstr;
     82        }

     83
     84        /// <summary>
     85        /// Creates an instance of the specified provider using the Cached
     86        /// ConstructorInfo from CreateConstructorInfo
     87        /// </summary>

     88        public static object Invoke(Provider dataProvider)
     89        {
     90            object[] paramArray = new object[2];
     91
     92            
     93            string dbOwner = null
     94            string connstring = null;
     95
     96            GetDataStoreParameters(dataProvider, out connstring, out dbOwner);
     97
     98            paramArray[0= dbOwner;
     99            paramArray[1= connstring;
    100
    101            return CreateConstructorInfo(dataProvider).Invoke(paramArray);
    102        }

    103
    104        Exception

      通过Type.GetType()来进行类的反射,当然我们需要对其进行实例化才能调用abstract class中的方法和属性,这就要用到Activator.CreateInstance(type,new object[]{databaseOwner,connectionString}),这个方法对类进行了实例化,当然实例化这个类的构造函数中的参数为(databaseOwner,connectionString);当查找到这个构造函数进行实例化时也将DataProvider中所得到的databaseOwner,connectionString两个变量的值传递给了参数。

      OK这样就完成了整个实现过程,如果有不对的地方请批评指正!
  • 相关阅读:
    改Android手机定位位置
    设计模式-行为型模式
    设计模式-结构型模式
    设计模式-创建型模式
    LoadRunner改脚本
    交互设计流程
    java正则过滤特殊字符
    js正则表达式判断非法字符 .(转)
    <BEA-141281> <unable to get file lock, will retry ...> (转)
    JAVA调用打印机打印指定文件
  • 原文地址:https://www.cnblogs.com/xdotnet/p/provider_extend_of_cs.html
Copyright © 2020-2023  润新知