下面我们来看看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
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这样就完成了整个实现过程,如果有不对的地方请批评指正!