1 //------------------------------------------------------------------------------
2 // <copyright file="DbProviderFactoriesConfigurationHandler.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 // <owner current="true" primary="true">Microsoft</owner>
6 // <owner current="true" primary="false">Microsoft</owner>
7 //------------------------------------------------------------------------------
9 namespace System
.Data
.Common
{
12 using System
.Collections
;
13 using System
.Configuration
;
15 using System
.Diagnostics
;
16 using System
.Globalization
;
19 // VSTFDevDiv # 624213: System.Data.Common.DbProviderFactories.GetFactoryClasses() still gets OracleClient provider in ClientSku environment.
20 // NOTES: As part of this bug fix, the decision was taken to make it consistent and to remove all the framework
21 // providers from the list in the machine.config file. The DbProviderFactories section of the machine.config will contain only
22 // custom providers names and details.
23 internal enum DbProvidersIndex
: int
29 DbProvidersIndexCount
// As enums are 0-based index, the DbProvidersIndexCount will hold the maximum count of the enum objects;
32 internal class DbProviderFactoryConfigSection
38 string assemblyQualifiedName
;
40 public DbProviderFactoryConfigSection(Type FactoryType
, string FactoryName
, string FactoryDescription
)
44 factType
= FactoryType
;
46 invariantName
= factType
.Namespace
.ToString();
47 description
= FactoryDescription
;
48 assemblyQualifiedName
= factType
.AssemblyQualifiedName
.ToString();
54 invariantName
= string.Empty
;
55 description
= string.Empty
;
56 assemblyQualifiedName
= string.Empty
;
60 public DbProviderFactoryConfigSection(string FactoryName
, string FactoryInvariantName
, string FactoryDescription
, string FactoryAssemblyQualifiedName
)
64 invariantName
= FactoryInvariantName
;
65 description
= FactoryDescription
;
66 assemblyQualifiedName
= FactoryAssemblyQualifiedName
;
71 if ((factType
== null) && (invariantName
== string.Empty
))
82 public string InvariantName
84 get { return invariantName; }
87 public string Description
89 get { return description; }
92 public string AssemblyQualifiedName
94 get { return assemblyQualifiedName; }
99 // <section name="system.data" type="System.Data.Common.DbProviderFactoriesConfigurationHandler, System.Data, Version=%ASSEMBLY_VERSION%, Culture=neutral, PublicKeyToken=%ECMA_PUBLICKEY%" />
102 // <DbProviderFactories>
103 // <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%"/>
104 // <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%"/>
105 // <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%"/>
106 // <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%"/>
107 // </DbProviderFactories>
109 // this class is delayed created, use ConfigurationSettings.GetSection("system.data") to obtain
110 public class DbProviderFactoriesConfigurationHandler
: IConfigurationSectionHandler
{ // V1.2.3300
111 internal const string sectionName
= "system.data";
112 internal const string providerGroup
= "DbProviderFactories";
114 // NOTES: Framework-Based DbProviderFactories Details
115 internal const string odbcProviderName
= "Odbc Data Provider";
116 internal const string odbcProviderDescription
= ".Net Framework Data Provider for Odbc";
118 internal const string oledbProviderName
= "OleDb Data Provider";
119 internal const string oledbProviderDescription
= ".Net Framework Data Provider for OleDb";
121 internal const string oracleclientProviderName
= "OracleClient Data Provider";
122 internal const string oracleclientProviderNamespace
= "System.Data.OracleClient";
123 internal const string oracleclientProviderDescription
= ".Net Framework Data Provider for Oracle";
125 internal const string sqlclientProviderName
= "SqlClient Data Provider";
126 internal const string sqlclientProviderDescription
= ".Net Framework Data Provider for SqlServer";
128 internal const string sqlclientPartialAssemblyQualifiedName
= "System.Data.SqlClient.SqlClientFactory, System.Data,";
129 internal const string oracleclientPartialAssemblyQualifiedName
= "System.Data.OracleClient.OracleClientFactory, System.Data.OracleClient,";
131 public DbProviderFactoriesConfigurationHandler() { // V1.2.3300
134 virtual public object Create(object parent
, object configContext
, XmlNode section
) { // V1.2.3300
138 return CreateStatic(parent
, configContext
, section
);
142 ADP
.TraceExceptionWithoutRethrow(e
); // it will be rethrown
148 static internal object CreateStatic(object parent
, object configContext
, XmlNode section
) {
149 object config
= parent
;
150 if (null != section
) {
151 config
= HandlerBase
.CloneParent(parent
as DataSet
, false);
152 bool foundFactories
= false;
154 HandlerBase
.CheckForUnrecognizedAttributes(section
);
155 foreach (XmlNode child
in section
.ChildNodes
) {
156 if (HandlerBase
.IsIgnorableAlsoCheckForNonElement(child
)) {
159 string sectionGroup
= child
.Name
;
160 switch(sectionGroup
) {
161 case DbProviderFactoriesConfigurationHandler
.providerGroup
:
162 if (foundFactories
) {
163 throw ADP
.ConfigSectionsUnique(DbProviderFactoriesConfigurationHandler
.providerGroup
);
165 foundFactories
= true;
166 HandleProviders(config
as DataSet
, configContext
, child
, sectionGroup
);
169 throw ADP
.ConfigUnrecognizedElement(child
);
176 // sectionName - i.e. "providerconfiguration"
177 private static void HandleProviders(DataSet config
, object configContext
, XmlNode section
, string sectionName
) {
178 DataTableCollection tables
= config
.Tables
;
179 DataTable dataTable
= tables
[sectionName
];
180 bool tableExisted
= (null != dataTable
);
181 dataTable
= DbProviderDictionarySectionHandler
.CreateStatic(dataTable
, configContext
, section
);
183 tables
.Add(dataTable
);
187 // based off of DictionarySectionHandler
188 private static class DbProviderDictionarySectionHandler
/* : IConfigurationSectionHandler*/ {
190 internal DbProviderDictionarySectionHandler() {
193 public object Create(Object parent, Object context, XmlNode section) {
194 return CreateStatic(parent, context, section);
198 static internal DataTable
CreateStatic(DataTable config
, Object context
, XmlNode section
) {
199 if (null != section
) {
200 HandlerBase
.CheckForUnrecognizedAttributes(section
);
202 if (null == config
) {
203 config
= DbProviderFactoriesConfigurationHandler
.CreateProviderDataTable();
205 // else already copied via DataSet.Copy
207 foreach (XmlNode child
in section
.ChildNodes
) {
208 if (HandlerBase
.IsIgnorableAlsoCheckForNonElement(child
)) {
213 HandleAdd(child
, config
);
216 HandleRemove(child
, config
);
219 HandleClear(child
, config
);
222 throw ADP
.ConfigUnrecognizedElement(child
);
225 config
.AcceptChanges();
229 static private void HandleAdd(XmlNode child
, DataTable config
) {
230 HandlerBase
.CheckForChildNodes(child
);
231 DataRow values
= config
.NewRow();
232 values
[0] = HandlerBase
.RemoveAttribute(child
, "name", true, false);
233 values
[1] = HandlerBase
.RemoveAttribute(child
, "description", true, false);
234 values
[2] = HandlerBase
.RemoveAttribute(child
, "invariant", true, false);
235 values
[3] = HandlerBase
.RemoveAttribute(child
, "type", true, false);
237 // because beta shipped recognizing "support=hex#", need to give
238 // more time for other providers to remove it from the .config files
239 HandlerBase
.RemoveAttribute(child
, "support", false, false);
241 HandlerBase
.CheckForUnrecognizedAttributes(child
);
242 config
.Rows
.Add(values
);
244 static private void HandleRemove(XmlNode child
, DataTable config
) {
245 HandlerBase
.CheckForChildNodes(child
);
246 String invr
= HandlerBase
.RemoveAttribute(child
, "invariant", true, false);
247 HandlerBase
.CheckForUnrecognizedAttributes(child
);
248 DataRow row
= config
.Rows
.Find(invr
);
249 if (null != row
) { // ignore invariants that don't exist
253 static private void HandleClear(XmlNode child
, DataTable config
) {
254 HandlerBase
.CheckForChildNodes(child
);
255 HandlerBase
.CheckForUnrecognizedAttributes(child
);
260 internal static DataTable
CreateProviderDataTable() {
261 DataColumn frme
= new DataColumn("Name", typeof(string));
262 frme
.ReadOnly
= true;
263 DataColumn desc
= new DataColumn("Description", typeof(string));
264 desc
.ReadOnly
= true;
265 DataColumn invr
= new DataColumn("InvariantName", typeof(string));
266 invr
.ReadOnly
= true;
267 DataColumn qual
= new DataColumn("AssemblyQualifiedName", typeof(string));
268 qual
.ReadOnly
= true;
270 DataColumn
[] primaryKey
= new DataColumn
[] { invr }
;
271 DataColumn
[] columns
= new DataColumn
[] {frme, desc, invr, qual }
;
272 DataTable table
= new DataTable(DbProviderFactoriesConfigurationHandler
.providerGroup
);
273 table
.Locale
= CultureInfo
.InvariantCulture
;
274 table
.Columns
.AddRange(columns
);
275 table
.PrimaryKey
= primaryKey
;