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

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

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

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

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

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

  1 None.gif public   sealed   class  DataProviders
  2 ExpandedBlockStart.gif     {
  3ExpandedSubBlockStart.gif        /// <summary>
  4InBlock.gif        /// This class can not be instantiated
  5ExpandedSubBlockEnd.gif        /// </summary>
  6InBlock.gif        private DataProviders()
  7ExpandedSubBlockStart.gif        {
  8ExpandedSubBlockEnd.gif        }
  9InBlock.gif
 10InBlock.gif        private static void GetDataStoreParameters(Provider dataProvider, out string connectionString, out string databaseOwner)
 11ExpandedSubBlockStart.gif        {
 12InBlock.gif            databaseOwner = dataProvider.Attributes["databaseOwner"];
 13InBlock.gif            if(databaseOwner == null || databaseOwner.Trim().Length == 0)
 14InBlock.gif                databaseOwner = ConfigurationSettings.AppSettings[dataProvider.Attributes["databaseOwnerStringName"]];
 15InBlock.gif
 16InBlock.gif            connectionString = dataProvider.Attributes["connectionString"];
 17InBlock.gif            if(connectionString == null || connectionString.Trim().Length == 0)
 18InBlock.gif                connectionString = ConfigurationSettings.AppSettings[dataProvider.Attributes["connectionStringName"]];
 19ExpandedSubBlockEnd.gif        }
 20InBlock.gif
 21ExpandedSubBlockStart.gif        /// <summary>
 22InBlock.gif        /// Creates an instance of the provider using Activator. This instance should be
 23InBlock.gif        /// cached since it is an expesivie operation
 24ExpandedSubBlockEnd.gif        /// </summary>
 25InBlock.gif        public static object CreateInstance(Provider dataProvider)
 26ExpandedSubBlockStart.gif        {
 27InBlock.gif            //Find the current attributes
 28InBlock.gif            string connectionString = null//dataProvider.Attributes["connectionString"];
 29InBlock.gif            string databaseOwner = null;// dataProvider.Attributes["databaseOwner"];
 30InBlock.gif
 31InBlock.gif            GetDataStoreParameters(dataProvider, out connectionString, out databaseOwner);
 32InBlock.gif
 33InBlock.gif            //Get the type
 34InBlock.gif            Type type  = Type.GetType(dataProvider.Type);
 35InBlock.gif
 36InBlock.gif            object newObject = null;
 37InBlock.gif            if(type != null)
 38ExpandedSubBlockStart.gif            {
 39ExpandedSubBlockStart.gif                newObject =  Activator.CreateInstance(type,new object[]{databaseOwner,connectionString});  
 40ExpandedSubBlockEnd.gif            }
 41InBlock.gif            
 42InBlock.gif            if(newObject == null//If we can not create an instance, throw an exception
 43InBlock.gif                ProviderException(dataProvider.Name);
 44InBlock.gif
 45InBlock.gif            return newObject;
 46ExpandedSubBlockEnd.gif        }
 47InBlock.gif
 48ExpandedSubBlockStart.gif        /// <summary>
 49InBlock.gif        /// Creates and Caches the ConstructorInfo for the specified provider. 
 50ExpandedSubBlockEnd.gif        /// </summary>
 51InBlock.gif        public static ConstructorInfo CreateConstructorInfo (Provider dataProvider) 
 52ExpandedSubBlockStart.gif        {
 53InBlock.gif
 54InBlock.gif            // The assembly should be in \bin or GAC, so we simply need
 55InBlock.gif            // to get an instance of the type
 56InBlock.gif            //
 57InBlock.gif            CSConfiguration config = CSConfiguration.GetConfig();
 58InBlock.gif            ConstructorInfo providerCnstr = null;
 59InBlock.gif            try 
 60ExpandedSubBlockStart.gif            {
 61InBlock.gif                //string providerTypeName = ((Provider) config.Providers[providerName]).Type;
 62InBlock.gif                Type type  = Type.GetType( dataProvider.Type );
 63InBlock.gif
 64InBlock.gif                // Insert the type into the cache
 65InBlock.gif                //
 66InBlock.gif                Type[] paramTypes = new Type[2];
 67InBlock.gif                paramTypes[0= typeof(string);
 68InBlock.gif                paramTypes[1= typeof(string);
 69InBlock.gif
 70InBlock.gif                providerCnstr = type.GetConstructor(paramTypes);
 71InBlock.gif
 72ExpandedSubBlockEnd.gif            } 
 73InBlock.gif            catch 
 74ExpandedSubBlockStart.gif            {
 75InBlock.gif                ProviderException(dataProvider.Name);
 76ExpandedSubBlockEnd.gif            }
 77InBlock.gif
 78InBlock.gif           if(providerCnstr == null)
 79InBlock.gif               ProviderException(dataProvider.Name);
 80InBlock.gif
 81InBlock.gif            return providerCnstr;
 82ExpandedSubBlockEnd.gif        }
 83InBlock.gif
 84ExpandedSubBlockStart.gif        /// <summary>
 85InBlock.gif        /// Creates an instance of the specified provider using the Cached
 86InBlock.gif        /// ConstructorInfo from CreateConstructorInfo
 87ExpandedSubBlockEnd.gif        /// </summary>
 88InBlock.gif        public static object Invoke(Provider dataProvider)
 89ExpandedSubBlockStart.gif        {
 90InBlock.gif            object[] paramArray = new object[2];
 91InBlock.gif
 92InBlock.gif            
 93InBlock.gif            string dbOwner = null
 94InBlock.gif            string connstring = null;
 95InBlock.gif
 96InBlock.gif            GetDataStoreParameters(dataProvider, out connstring, out dbOwner);
 97InBlock.gif
 98InBlock.gif            paramArray[0= dbOwner;
 99InBlock.gif            paramArray[1= connstring;
100InBlock.gif
101InBlock.gif            return CreateConstructorInfo(dataProvider).Invoke(paramArray);
102ExpandedSubBlockEnd.gif        }
103InBlock.gif
104ContractedSubBlock.gif        Exception

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


本文转自网魂小兵博客园博客,原文链接:http://www.cnblogs.com/xdotnet/archive/2006/10/15/provider_extend_of_cs.html,如需转载请自行联系原作者

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值