@@ -23,16 +23,16 @@ internal static class DbConnectionFactory
23
23
private static readonly ConcurrentDictionary < string , CachedFactory > factoryCache =
24
24
new ConcurrentDictionary < string , CachedFactory > ( ) ;
25
25
26
- private static readonly Dictionary < string , Tuple < string , string > > providerFactoryTypeMap =
27
- new Dictionary < string , Tuple < string , string > >
26
+ private static readonly Dictionary < string , List < Tuple < string , string > > > providerFactoryTypeMap =
27
+ new Dictionary < string , List < Tuple < string , string > > >
28
28
{
29
- { AdoNetInvariants . InvariantNameSqlServer , new Tuple < string , string > ( "System.Data.SqlClient" , "System.Data.SqlClient.SqlClientFactory" ) } ,
30
- { AdoNetInvariants . InvariantNameMySql , new Tuple < string , string > ( "MySql.Data" , "MySql.Data.MySqlClient.MySqlClientFactory" ) } ,
31
- { AdoNetInvariants . InvariantNameOracleDatabase , new Tuple < string , string > ( "Oracle.ManagedDataAccess" , "Oracle.ManagedDataAccess.Client.OracleClientFactory" ) } ,
32
- { AdoNetInvariants . InvariantNamePostgreSql , new Tuple < string , string > ( "Npgsql" , "Npgsql.NpgsqlFactory" ) } ,
33
- { AdoNetInvariants . InvariantNameSqlLite , new Tuple < string , string > ( "Microsoft.Data.SQLite" , "Microsoft.Data.SQLite.SqliteFactory" ) } ,
34
- { AdoNetInvariants . InvariantNameSqlServerDotnetCore , new Tuple < string , string > ( "Microsoft.Data.SqlClient" , "Microsoft.Data.SqlClient.SqlClientFactory" ) } ,
35
- { AdoNetInvariants . InvariantNameMySqlConnector , new Tuple < string , string > ( "MySqlConnector" , "MySql.Data.MySqlClient.MySqlClientFactory" ) } ,
29
+ { AdoNetInvariants . InvariantNameSqlServer , new List < Tuple < string , string > > { new Tuple < string , string > ( "System.Data.SqlClient" , "System.Data.SqlClient.SqlClientFactory" ) } } ,
30
+ { AdoNetInvariants . InvariantNameMySql , new List < Tuple < string , string > > { new Tuple < string , string > ( "MySql.Data" , "MySql.Data.MySqlClient.MySqlClientFactory" ) } } ,
31
+ { AdoNetInvariants . InvariantNameOracleDatabase , new List < Tuple < string , string > > { new Tuple < string , string > ( "Oracle.ManagedDataAccess" , "Oracle.ManagedDataAccess.Client.OracleClientFactory" ) } } ,
32
+ { AdoNetInvariants . InvariantNamePostgreSql , new List < Tuple < string , string > > { new Tuple < string , string > ( "Npgsql" , "Npgsql.NpgsqlFactory" ) } } ,
33
+ { AdoNetInvariants . InvariantNameSqlLite , new List < Tuple < string , string > > { new Tuple < string , string > ( "Microsoft.Data.SQLite" , "Microsoft.Data.SQLite.SqliteFactory" ) } } ,
34
+ { AdoNetInvariants . InvariantNameSqlServerDotnetCore , new List < Tuple < string , string > > { new Tuple < string , string > ( "Microsoft.Data.SqlClient" , "Microsoft.Data.SqlClient.SqlClientFactory" ) } } ,
35
+ { AdoNetInvariants . InvariantNameMySqlConnector , new List < Tuple < string , string > > { new Tuple < string , string > ( "MySqlConnector" , "MySqlConnector.MySqlConnectorFactory" ) , new Tuple < string , string > ( "MySqlConnector" , " MySql.Data.MySqlClient.MySqlClientFactory") } } ,
36
36
} ;
37
37
38
38
private static CachedFactory GetFactory ( string invariantName )
@@ -42,34 +42,59 @@ private static CachedFactory GetFactory(string invariantName)
42
42
throw new ArgumentNullException ( nameof ( invariantName ) ) ;
43
43
}
44
44
45
- Tuple < string , string > providerFactoryDefinition ;
46
- if ( ! providerFactoryTypeMap . TryGetValue ( invariantName , out providerFactoryDefinition ) )
45
+ List < Tuple < string , string > > providerFactoryDefinitions ;
46
+ if ( ! providerFactoryTypeMap . TryGetValue ( invariantName , out providerFactoryDefinitions ) || providerFactoryDefinitions . Count == 0 )
47
47
throw new InvalidOperationException ( $ "Database provider factory with '{ invariantName } ' invariant name not supported.") ;
48
48
49
- Assembly asm ;
50
- try
49
+ List < Exception > exceptions = null ;
50
+ foreach ( var providerFactoryDefinition in providerFactoryDefinitions )
51
51
{
52
- var asmName = new AssemblyName ( providerFactoryDefinition . Item1 ) ;
53
- asm = Assembly . Load ( asmName ) ;
52
+ Assembly asm = null ;
53
+ try
54
+ {
55
+ var asmName = new AssemblyName ( providerFactoryDefinition . Item1 ) ;
56
+ asm = Assembly . Load ( asmName ) ;
57
+ }
58
+ catch ( Exception exc )
59
+ {
60
+ AddException ( new InvalidOperationException ( $ "Unable to find and/or load a candidate assembly '{ providerFactoryDefinition . Item1 } ' for '{ invariantName } ' invariant name.", exc ) ) ;
61
+ continue ;
62
+ }
63
+
64
+ if ( asm == null )
65
+ {
66
+ AddException ( new InvalidOperationException ( $ "Can't find database provider factory with '{ invariantName } ' invariant name. Please make sure that your ADO.Net provider package library is deployed with your application.") ) ;
67
+ continue ;
68
+ }
69
+
70
+ var providerFactoryType = asm . GetType ( providerFactoryDefinition . Item2 ) ;
71
+ if ( providerFactoryType == null )
72
+ {
73
+ AddException ( new InvalidOperationException ( $ "Unable to load type '{ providerFactoryDefinition . Item2 } ' for '{ invariantName } ' invariant name.") ) ;
74
+ continue ;
75
+ }
76
+
77
+ var prop = providerFactoryType . GetFields ( ) . SingleOrDefault ( p => string . Equals ( p . Name , "Instance" , StringComparison . OrdinalIgnoreCase ) && p . IsStatic ) ;
78
+ if ( prop == null )
79
+ {
80
+ AddException ( new InvalidOperationException ( $ "Invalid provider type '{ providerFactoryDefinition . Item2 } ' for '{ invariantName } ' invariant name.") ) ;
81
+ continue ;
82
+ }
83
+
84
+ var factory = ( DbProviderFactory ) prop . GetValue ( null ) ;
85
+ return new CachedFactory ( factory , providerFactoryType . Name , "" , providerFactoryType . AssemblyQualifiedName ) ;
54
86
}
55
- catch ( Exception exc )
56
- {
57
- throw new InvalidOperationException ( $ "Unable to find and/or load a candidate assembly for '{ invariantName } ' invariant name.", exc ) ;
58
- }
59
-
60
- if ( asm == null )
61
- throw new InvalidOperationException ( $ "Can't find database provider factory with '{ invariantName } ' invariant name. Please make sure that your ADO.Net provider package library is deployed with your application.") ;
62
87
63
- var providerFactoryType = asm . GetType ( providerFactoryDefinition . Item2 ) ;
64
- if ( providerFactoryType == null )
65
- throw new InvalidOperationException ( $ "Unable to load type '{ providerFactoryDefinition . Item2 } ' for '{ invariantName } ' invariant name.") ;
88
+ throw new AggregateException ( exceptions ) ;
66
89
67
- var prop = providerFactoryType . GetFields ( ) . SingleOrDefault ( p => string . Equals ( p . Name , "Instance" , StringComparison . OrdinalIgnoreCase ) && p . IsStatic ) ;
68
- if ( prop == null )
69
- throw new InvalidOperationException ( $ "Invalid provider type '{ providerFactoryDefinition . Item2 } ' for '{ invariantName } ' invariant name.") ;
70
-
71
- var factory = ( DbProviderFactory ) prop . GetValue ( null ) ;
72
- return new CachedFactory ( factory , providerFactoryType . Name , "" , providerFactoryType . AssemblyQualifiedName ) ;
90
+ void AddException ( Exception ex )
91
+ {
92
+ if ( exceptions == null )
93
+ {
94
+ exceptions = new List < Exception > ( ) ;
95
+ }
96
+ exceptions . Add ( ex ) ;
97
+ }
73
98
}
74
99
75
100
public static DbConnection CreateConnection ( string invariantName , string connectionString )
0 commit comments