DbProviderFactoriesConfigurationHandler.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. //------------------------------------------------------------------------------
  2. // <copyright file="DbProviderFactoriesConfigurationHandler.cs" company="Microsoft">
  3. // Copyright (c) Microsoft Corporation. All rights reserved.
  4. // </copyright>
  5. // <owner current="true" primary="true">Microsoft</owner>
  6. // <owner current="true" primary="false">Microsoft</owner>
  7. //------------------------------------------------------------------------------
  8. namespace System.Data.Common {
  9. using System;
  10. using System.Collections;
  11. using System.Configuration;
  12. using System.Data;
  13. using System.Diagnostics;
  14. using System.Globalization;
  15. using System.Xml;
  16. // VSTFDevDiv # 624213: System.Data.Common.DbProviderFactories.GetFactoryClasses() still gets OracleClient provider in ClientSku environment.
  17. // NOTES: As part of this bug fix, the decision was taken to make it consistent and to remove all the framework
  18. // providers from the list in the machine.config file. The DbProviderFactories section of the machine.config will contain only
  19. // custom providers names and details.
  20. internal enum DbProvidersIndex : int
  21. {
  22. Odbc = 0,
  23. OleDb,
  24. OracleClient,
  25. SqlClient,
  26. DbProvidersIndexCount // As enums are 0-based index, the DbProvidersIndexCount will hold the maximum count of the enum objects;
  27. }
  28. internal class DbProviderFactoryConfigSection
  29. {
  30. Type factType;
  31. string name;
  32. string invariantName;
  33. string description;
  34. string assemblyQualifiedName;
  35. public DbProviderFactoryConfigSection(Type FactoryType, string FactoryName, string FactoryDescription)
  36. {
  37. try
  38. {
  39. factType = FactoryType;
  40. name = FactoryName;
  41. invariantName = factType.Namespace.ToString();
  42. description = FactoryDescription;
  43. assemblyQualifiedName = factType.AssemblyQualifiedName.ToString();
  44. }
  45. catch
  46. {
  47. factType = null;
  48. name = string.Empty;
  49. invariantName = string.Empty;
  50. description = string.Empty;
  51. assemblyQualifiedName = string.Empty;
  52. }
  53. }
  54. public DbProviderFactoryConfigSection(string FactoryName, string FactoryInvariantName, string FactoryDescription, string FactoryAssemblyQualifiedName)
  55. {
  56. factType = null;
  57. name = FactoryName;
  58. invariantName = FactoryInvariantName;
  59. description = FactoryDescription;
  60. assemblyQualifiedName = FactoryAssemblyQualifiedName;
  61. }
  62. public bool IsNull()
  63. {
  64. if ((factType == null) && (invariantName == string.Empty))
  65. return true;
  66. else
  67. return false;
  68. }
  69. public string Name
  70. {
  71. get { return name; }
  72. }
  73. public string InvariantName
  74. {
  75. get { return invariantName; }
  76. }
  77. public string Description
  78. {
  79. get { return description; }
  80. }
  81. public string AssemblyQualifiedName
  82. {
  83. get { return assemblyQualifiedName; }
  84. }
  85. }
  86. // <configSections>
  87. // <section name="system.data" type="System.Data.Common.DbProviderFactoriesConfigurationHandler, System.Data, Version=%ASSEMBLY_VERSION%, Culture=neutral, PublicKeyToken=%ECMA_PUBLICKEY%" />
  88. // </configSections>
  89. // <system.data>
  90. // <DbProviderFactories>
  91. // <add name="Odbc Data Provider" invariant="System.Data.Odbc" support="1BF" description=".Net Framework Data Provider for Odbc" type="System.Data.Odbc.OdbcFactory, System.Data, Version=%ASSEMBLY_VERSION%, Culture=neutral, PublicKeyToken=%ECMA_PUBLICKEY%"/>
  92. // <add name="OleDb Data Provider" invariant="System.Data.OleDb" support="1BF" description=".Net Framework Data Provider for OleDb" type="System.Data.OleDb.OleDbFactory, System.Data, Version=%ASSEMBLY_VERSION%, Culture=neutral, PublicKeyToken=%ECMA_PUBLICKEY%"/>
  93. // <add name="OracleClient Data Provider" invariant="System.Data.OracleClient" support="1AF" description=".Net Framework Data Provider for Oracle" type="System.Data.OracleClient.OracleFactory, System.Data.OracleClient, Version=%ASSEMBLY_VERSION%, Culture=neutral, PublicKeyToken=%ECMA_PUBLICKEY%"/>
  94. // <add name="SqlClient Data Provider" invariant="System.Data.SqlClient" support="1FF" description=".Net Framework Data Provider for SqlServer" type="System.Data.SqlClient.SqlClientFactory, System.Data, Version=%ASSEMBLY_VERSION%, Culture=neutral, PublicKeyToken=%ECMA_PUBLICKEY%"/>
  95. // </DbProviderFactories>
  96. // </system.data>
  97. // this class is delayed created, use ConfigurationSettings.GetSection("system.data") to obtain
  98. public class DbProviderFactoriesConfigurationHandler : IConfigurationSectionHandler { // V1.2.3300
  99. internal const string sectionName = "system.data";
  100. internal const string providerGroup = "DbProviderFactories";
  101. // NOTES: Framework-Based DbProviderFactories Details
  102. internal const string odbcProviderName = "Odbc Data Provider";
  103. internal const string odbcProviderDescription = ".Net Framework Data Provider for Odbc";
  104. internal const string oledbProviderName = "OleDb Data Provider";
  105. internal const string oledbProviderDescription = ".Net Framework Data Provider for OleDb";
  106. internal const string oracleclientProviderName = "OracleClient Data Provider";
  107. internal const string oracleclientProviderNamespace = "System.Data.OracleClient";
  108. internal const string oracleclientProviderDescription = ".Net Framework Data Provider for Oracle";
  109. internal const string sqlclientProviderName = "SqlClient Data Provider";
  110. internal const string sqlclientProviderDescription = ".Net Framework Data Provider for SqlServer";
  111. internal const string sqlclientPartialAssemblyQualifiedName = "System.Data.SqlClient.SqlClientFactory, System.Data,";
  112. internal const string oracleclientPartialAssemblyQualifiedName = "System.Data.OracleClient.OracleClientFactory, System.Data.OracleClient,";
  113. public DbProviderFactoriesConfigurationHandler() { // V1.2.3300
  114. }
  115. virtual public object Create(object parent, object configContext, XmlNode section) { // V1.2.3300
  116. #if DEBUG
  117. try {
  118. #endif
  119. return CreateStatic(parent, configContext, section);
  120. #if DEBUG
  121. }
  122. catch(Exception e) {
  123. ADP.TraceExceptionWithoutRethrow(e); // it will be rethrown
  124. throw;
  125. }
  126. #endif
  127. }
  128. static internal object CreateStatic(object parent, object configContext, XmlNode section) {
  129. object config = parent;
  130. if (null != section) {
  131. config = HandlerBase.CloneParent(parent as DataSet, false);
  132. bool foundFactories = false;
  133. HandlerBase.CheckForUnrecognizedAttributes(section);
  134. foreach (XmlNode child in section.ChildNodes) {
  135. if (HandlerBase.IsIgnorableAlsoCheckForNonElement(child)) {
  136. continue;
  137. }
  138. string sectionGroup = child.Name;
  139. switch(sectionGroup) {
  140. case DbProviderFactoriesConfigurationHandler.providerGroup:
  141. if (foundFactories) {
  142. throw ADP.ConfigSectionsUnique(DbProviderFactoriesConfigurationHandler.providerGroup);
  143. }
  144. foundFactories = true;
  145. HandleProviders(config as DataSet, configContext, child, sectionGroup);
  146. break;
  147. default:
  148. throw ADP.ConfigUnrecognizedElement(child);
  149. }
  150. }
  151. }
  152. return config;
  153. }
  154. // sectionName - i.e. "providerconfiguration"
  155. private static void HandleProviders(DataSet config, object configContext, XmlNode section, string sectionName) {
  156. DataTableCollection tables = config.Tables;
  157. DataTable dataTable = tables[sectionName];
  158. bool tableExisted = (null != dataTable);
  159. dataTable = DbProviderDictionarySectionHandler.CreateStatic(dataTable, configContext, section);
  160. if (!tableExisted) {
  161. tables.Add(dataTable);
  162. }
  163. }
  164. // based off of DictionarySectionHandler
  165. private static class DbProviderDictionarySectionHandler/* : IConfigurationSectionHandler*/ {
  166. /*
  167. internal DbProviderDictionarySectionHandler() {
  168. }
  169. public object Create(Object parent, Object context, XmlNode section) {
  170. return CreateStatic(parent, context, section);
  171. }
  172. */
  173. static internal DataTable CreateStatic(DataTable config, Object context, XmlNode section) {
  174. if (null != section) {
  175. HandlerBase.CheckForUnrecognizedAttributes(section);
  176. if (null == config) {
  177. config = DbProviderFactoriesConfigurationHandler.CreateProviderDataTable();
  178. }
  179. // else already copied via DataSet.Copy
  180. foreach (XmlNode child in section.ChildNodes) {
  181. if (HandlerBase.IsIgnorableAlsoCheckForNonElement(child)) {
  182. continue;
  183. }
  184. switch(child.Name) {
  185. case "add":
  186. HandleAdd(child, config);
  187. break;
  188. case "remove":
  189. HandleRemove(child, config);
  190. break;
  191. case "clear":
  192. HandleClear(child, config);
  193. break;
  194. default:
  195. throw ADP.ConfigUnrecognizedElement(child);
  196. }
  197. }
  198. config.AcceptChanges();
  199. }
  200. return config;
  201. }
  202. static private void HandleAdd(XmlNode child, DataTable config) {
  203. HandlerBase.CheckForChildNodes(child);
  204. DataRow values = config.NewRow();
  205. values[0] = HandlerBase.RemoveAttribute(child, "name", true, false);
  206. values[1] = HandlerBase.RemoveAttribute(child, "description", true, false);
  207. values[2] = HandlerBase.RemoveAttribute(child, "invariant", true, false);
  208. values[3] = HandlerBase.RemoveAttribute(child, "type", true, false);
  209. // because beta shipped recognizing "support=hex#", need to give
  210. // more time for other providers to remove it from the .config files
  211. HandlerBase.RemoveAttribute(child, "support", false, false);
  212. HandlerBase.CheckForUnrecognizedAttributes(child);
  213. config.Rows.Add(values);
  214. }
  215. static private void HandleRemove(XmlNode child, DataTable config) {
  216. HandlerBase.CheckForChildNodes(child);
  217. String invr = HandlerBase.RemoveAttribute(child, "invariant", true, false);
  218. HandlerBase.CheckForUnrecognizedAttributes(child);
  219. DataRow row = config.Rows.Find(invr);
  220. if (null != row) { // ignore invariants that don't exist
  221. row.Delete();
  222. }
  223. }
  224. static private void HandleClear(XmlNode child, DataTable config) {
  225. HandlerBase.CheckForChildNodes(child);
  226. HandlerBase.CheckForUnrecognizedAttributes(child);
  227. config.Clear();
  228. }
  229. }
  230. internal static DataTable CreateProviderDataTable() {
  231. DataColumn frme = new DataColumn("Name", typeof(string));
  232. frme.ReadOnly = true;
  233. DataColumn desc = new DataColumn("Description", typeof(string));
  234. desc.ReadOnly = true;
  235. DataColumn invr = new DataColumn("InvariantName", typeof(string));
  236. invr.ReadOnly = true;
  237. DataColumn qual = new DataColumn("AssemblyQualifiedName", typeof(string));
  238. qual.ReadOnly = true;
  239. DataColumn[] primaryKey = new DataColumn[] { invr };
  240. DataColumn[] columns = new DataColumn[] {frme, desc, invr, qual };
  241. DataTable table = new DataTable(DbProviderFactoriesConfigurationHandler.providerGroup);
  242. table.Locale = CultureInfo.InvariantCulture;
  243. table.Columns.AddRange(columns);
  244. table.PrimaryKey = primaryKey;
  245. return table;
  246. }
  247. }
  248. }