[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这样就完成了整个实现过程,如果有不对的地方请批评指正!
原文地址:https://www.cnblogs.com/xdotnet/p/provider_extend_of_cs.html