@@ -49,7 +49,12 @@ public sealed class MultiShardConnection : IDisposable
49
49
/// </summary>
50
50
private SqlConnectionInfo _connectionInfo ;
51
51
52
- #endregion
52
+ /// <summary>
53
+ /// The shard connections
54
+ /// </summary>
55
+ private List < Tuple < ShardLocation , DbConnection > > _shardConnections ;
56
+
57
+ #endregion
53
58
54
59
#region Ctors
55
60
@@ -89,14 +94,50 @@ public MultiShardConnection(IEnumerable<ShardLocation> shardLocations, string co
89
94
InitializeShardConnections ( shardLocations ) ;
90
95
}
91
96
97
+ /// <summary>
98
+ /// Initializes a new instance of the <see cref="MultiShardConnection"/> class.
99
+ /// </summary>
100
+ /// <param name="shards">The collection of <see cref="Shard"/>s used for this connection instances.</param>
101
+ /// <param name="connectionInfo">
102
+ /// These credentials will be used to connect to the <see cref="Shard"/>s.
103
+ /// The same credentials are used on all shards.
104
+ /// Therefore, all shards need to provide the appropriate permissions for these credentials to execute the command.
105
+ /// </param>
106
+ /// <remarks>
107
+ /// Multiple Active Result Sets (MARS) are not supported and are disabled for any processing at the shards.
108
+ /// </remarks>
109
+ public MultiShardConnection ( IEnumerable < Shard > shards , SqlConnectionInfo connectionInfo )
110
+ {
111
+ InitializeConnectionInfo ( connectionInfo ) ;
112
+ InitializeShardConnections ( shards ) ;
113
+ }
114
+
115
+ /// <summary>
116
+ /// Initializes a new instance of the <see cref="MultiShardConnection"/> class.
117
+ /// </summary>
118
+ /// <param name="shardLocations">The collection of <see cref="ShardLocation"/>s used for this connection instances.</param>
119
+ /// <param name="connectionInfo">
120
+ /// These credentials will be used to connect to the <see cref="Shard"/>s.
121
+ /// The same credentials are used on all shards.
122
+ /// Therefore, all shards need to provide the appropriate permissions for these credentials to execute the command.
123
+ /// </param>
124
+ /// <remarks>
125
+ /// Multiple Active Result Sets (MARS) are not supported and are disabled for any processing at the shards.
126
+ /// </remarks>
127
+ public MultiShardConnection ( IEnumerable < ShardLocation > shardLocations , SqlConnectionInfo connectionInfo )
128
+ {
129
+ InitializeConnectionInfo ( connectionInfo ) ;
130
+ InitializeShardConnections ( shardLocations ) ;
131
+ }
132
+
92
133
/// <summary>
93
134
/// Creates an instance of this class
94
135
/// /* TEST ONLY */
95
136
/// </summary>
96
137
/// <param name="shardConnections">Connections to the shards</param>
97
138
internal MultiShardConnection ( List < Tuple < ShardLocation , DbConnection > > shardConnections )
98
139
{
99
- this . ShardConnections = shardConnections ;
140
+ this . _shardConnections = shardConnections ;
100
141
}
101
142
102
143
#endregion
@@ -119,17 +160,11 @@ public IEnumerable<ShardLocation> ShardLocations
119
160
{
120
161
get
121
162
{
122
- return this . ShardConnections . Select ( s => s . Item1 ) ;
163
+ return this . _shardConnections . Select ( s => s . Item1 ) ;
123
164
}
124
165
}
125
166
126
- internal List < Tuple < ShardLocation , DbConnection > > ShardConnections
127
- {
128
- get ;
129
- private set ;
130
- }
131
-
132
- #endregion
167
+ #endregion
133
168
134
169
#region Public Methods
135
170
@@ -152,7 +187,7 @@ public void Dispose()
152
187
if ( ! _disposed )
153
188
{
154
189
// Dispose off the shard connections
155
- this . ShardConnections . ForEach (
190
+ this . _shardConnections . ForEach (
156
191
( c ) =>
157
192
{
158
193
if ( c . Item2 != null )
@@ -167,9 +202,35 @@ public void Dispose()
167
202
}
168
203
}
169
204
170
- #endregion
205
+ #endregion
206
+
207
+
208
+ #region Internal methods
209
+
210
+ /// <summary>
211
+ /// Gets the shard connections
212
+ /// </summary>
213
+ internal List < Tuple < ShardLocation , DbConnection > > GetShardConnections ( )
214
+ {
215
+ // Refresh the access tokens for all shard connections.
216
+ // (Null check because unit tests use internal code path which doesn't initialize _connectionInfo).
217
+ if ( this . _connectionInfo != null )
218
+ {
219
+ foreach ( var shardConnection in _shardConnections )
220
+ {
221
+ if ( shardConnection . Item2 != null )
222
+ {
223
+ this . _connectionInfo . RefreshAccessToken ( shardConnection . Item2 ) ;
224
+ }
225
+ }
226
+ }
171
227
172
- #region Helpers
228
+ return _shardConnections ;
229
+ }
230
+
231
+ #endregion
232
+
233
+ #region Helpers
173
234
174
235
private static void ValidateNotEmpty < T > (
175
236
IEnumerable < T > namedCollection ,
@@ -181,11 +242,28 @@ private static void ValidateNotEmpty<T>(
181
242
}
182
243
}
183
244
245
+ private void InitializeConnectionInfo ( SqlConnectionInfo connectionInfo )
246
+ {
247
+ if ( connectionInfo == null )
248
+ {
249
+ throw new ArgumentNullException ( "connectionInfo" ) ;
250
+ }
251
+
252
+ string updatedConnectionString = InitializeConnectionString ( connectionInfo . ConnectionString ) ;
253
+ this . _connectionInfo = connectionInfo . CloneWithUpdatedConnectionString ( updatedConnectionString ) ;
254
+ }
255
+
184
256
private void InitializeConnectionInfo ( string connectionString )
257
+ {
258
+ string updatedConnectionString = InitializeConnectionString ( connectionString ) ;
259
+ this . _connectionInfo = new SqlConnectionInfo ( updatedConnectionString ) ;
260
+ }
261
+
262
+ private static string InitializeConnectionString ( string connectionString )
185
263
{
186
264
if ( connectionString == null )
187
265
{
188
- throw new ArgumentNullException ( " connectionString" ) ;
266
+ throw new ArgumentNullException ( nameof ( connectionString ) ) ;
189
267
}
190
268
191
269
// Enhance the ApplicationName with this library's name as a suffix
@@ -206,7 +284,7 @@ private void InitializeConnectionInfo(string connectionString)
206
284
throw new ArgumentException ( "InitialCatalog must not be set in the connectionStringBuilder" ) ;
207
285
}
208
286
209
- this . _connectionInfo = new SqlConnectionInfo ( connectionStringBuilder . ToString ( ) ) ;
287
+ return connectionStringBuilder . ToString ( ) ;
210
288
}
211
289
212
290
private void InitializeShardConnections ( IEnumerable < Shard > shards )
@@ -220,8 +298,8 @@ private void InitializeShardConnections(IEnumerable<Shard> shards)
220
298
this . Shards = shards . ToList ( ) ;
221
299
ValidateNotEmpty ( this . Shards , "shards" ) ;
222
300
223
- this . ShardConnections = this . Shards . Select (
224
- s => CreateDbConnectionForLocation ( s . Location , _connectionInfo ) ) . ToList ( ) ;
301
+ this . _shardConnections = ( this . Shards . Select (
302
+ s => CreateDbConnectionForLocation ( s . Location , _connectionInfo ) ) . ToList ( ) ) ;
225
303
}
226
304
227
305
private void InitializeShardConnections ( IEnumerable < ShardLocation > shardLocations )
@@ -236,7 +314,7 @@ private void InitializeShardConnections(IEnumerable<ShardLocation> shardLocation
236
314
ValidateNotEmpty ( shardLocationsList , "shardLocations" ) ;
237
315
238
316
this . Shards = null ;
239
- this . ShardConnections = shardLocationsList . Select (
317
+ this . _shardConnections = shardLocationsList . Select (
240
318
s => CreateDbConnectionForLocation ( s , _connectionInfo ) ) . ToList ( ) ;
241
319
}
242
320
@@ -270,7 +348,7 @@ private static Tuple<ShardLocation, DbConnection> CreateDbConnectionForLocation(
270
348
[ System . Diagnostics . CodeAnalysis . SuppressMessage ( "Microsoft.Design" , "CA1031:DoNotCatchGeneralExceptionTypes" , Justification = "We do not want to throw on Close." ) ]
271
349
internal void Close ( )
272
350
{
273
- foreach ( var conn in this . ShardConnections )
351
+ foreach ( var conn in this . _shardConnections )
274
352
{
275
353
if ( conn . Item2 != null && conn . Item2 . State != ConnectionState . Closed )
276
354
{
0 commit comments