Skip to content

Commit d628e84

Browse files
committed
Move IMultiTenancyConnectionProvider to session factory configuration
1 parent 8c80941 commit d628e84

24 files changed

+217
-199
lines changed

src/NHibernate.Test/Async/MultiTenancy/DatabaseStrategyNoDbSpecificFixture.cs

+13-3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
using System.Runtime.Serialization.Formatters.Binary;
1717
using NHibernate.Cfg;
1818
using NHibernate.Cfg.MappingSchema;
19+
using NHibernate.Connection;
1920
using NHibernate.Dialect;
2021
using NHibernate.Driver;
2122
using NHibernate.Engine;
@@ -35,7 +36,12 @@ public class DatabaseStrategyNoDbSpecificFixtureAsync : TestCaseMappingByCode
3536

3637
protected override void Configure(Configuration configuration)
3738
{
38-
configuration.Properties[Cfg.Environment.MultiTenancy] = MultiTenancyStrategy.Database.ToString();
39+
configuration.DataBaseIntegration(
40+
x =>
41+
{
42+
x.MultiTenancy = MultiTenancyStrategy.Database;
43+
x.MultiTenancyConnectionProvider<TestMultiTenancyConnectionProvider>();
44+
});
3945
configuration.Properties[Cfg.Environment.GenerateStatistics] = "true";
4046
base.Configure(configuration);
4147
}
@@ -193,7 +199,10 @@ private IStatelessSession OpenTenantStatelessSession(string tenantId)
193199

194200
private TenantConfiguration GetTenantConfig(string tenantId)
195201
{
196-
return new TenantConfiguration(new TestTenantConnectionProvider(Sfi, tenantId, IsSqlServerDialect));
202+
return new TestTenantConfiguration(tenantId, IsSqlServerDialect)
203+
{
204+
ConnectionString = Sfi.ConnectionProvider.GetConnectionString()
205+
};
197206
}
198207

199208
private bool IsSqlServerDialect => Sfi.Dialect is MsSql2000Dialect && !(Sfi.ConnectionProvider.Driver is OdbcDriver);
@@ -217,7 +226,8 @@ protected override HbmMapping GetMappings()
217226

218227
protected override DbConnection OpenConnectionForSchemaExport()
219228
{
220-
return GetTenantConfig("defaultTenant").ConnectionAccess.GetConnection();
229+
return Sfi.Settings.MultiTenancyConnectionProvider
230+
.GetConnectionAccess(GetTenantConfig("defaultTenant")).GetConnection(Sfi.ConnectionProvider);
221231
}
222232

223233
protected override ISession OpenSession()

src/NHibernate.Test/MultiTenancy/DatabaseStrategyNoDbSpecificFixture.cs

+15-21
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Runtime.Serialization.Formatters.Binary;
77
using NHibernate.Cfg;
88
using NHibernate.Cfg.MappingSchema;
9+
using NHibernate.Connection;
910
using NHibernate.Dialect;
1011
using NHibernate.Driver;
1112
using NHibernate.Engine;
@@ -24,23 +25,20 @@ public class DatabaseStrategyNoDbSpecificFixture : TestCaseMappingByCode
2425

2526
protected override void Configure(Configuration configuration)
2627
{
27-
configuration.Properties[Cfg.Environment.MultiTenancy] = MultiTenancyStrategy.Database.ToString();
28+
configuration.DataBaseIntegration(
29+
x =>
30+
{
31+
x.MultiTenancy = MultiTenancyStrategy.Database;
32+
x.MultiTenancyConnectionProvider<TestMultiTenancyConnectionProvider>();
33+
});
2834
configuration.Properties[Cfg.Environment.GenerateStatistics] = "true";
2935
base.Configure(configuration);
3036
}
3137

3238
[Test]
3339
public void ShouldThrowWithNoTenantIdentifier()
3440
{
35-
var sessionBuilder = Sfi.WithOptions().TenantConfiguration(new TenantConfiguration(new MockConnectionProvider(null, null)));
36-
37-
Assert.That(() => sessionBuilder.OpenSession(), Throws.ArgumentException);
38-
}
39-
40-
[Test]
41-
public void ShouldThrowWithNoConnectionAccess()
42-
{
43-
var sessionBuilder = Sfi.WithOptions().TenantConfiguration(new TenantConfiguration(new MockConnectionProvider("tenant1", null)));
41+
var sessionBuilder = Sfi.WithOptions().TenantConfiguration(new TenantConfiguration(null));
4442

4543
Assert.That(() => sessionBuilder.OpenSession(), Throws.ArgumentException);
4644
}
@@ -65,19 +63,11 @@ public void DifferentConnectionStringForDifferentTenants()
6563
[Test]
6664
public void StatelessSessionShouldThrowWithNoTenantIdentifier()
6765
{
68-
var sessionBuilder = Sfi.WithStatelessOptions().TenantConfiguration(new TenantConfiguration(new MockConnectionProvider(null, null)));
66+
var sessionBuilder = Sfi.WithStatelessOptions().TenantConfiguration(new TenantConfiguration(null));
6967

7068
Assert.That(() => sessionBuilder.OpenStatelessSession(), Throws.ArgumentException);
7169
}
7270

73-
[Test]
74-
public void StatelessSessionShouldThrowWithNoConnectionAccess()
75-
{
76-
var sessionBuilder = Sfi.WithStatelessOptions().TenantConfiguration(new TenantConfiguration(new MockConnectionProvider("tenant1", null)));
77-
78-
Assert.That(() => sessionBuilder.OpenStatelessSession(), Throws.ArgumentException);
79-
}
80-
8171
[Test]
8272
public void StatelessSessionDifferentConnectionStringForDifferentTenants()
8373
{
@@ -282,7 +272,10 @@ private IStatelessSession OpenTenantStatelessSession(string tenantId)
282272

283273
private TenantConfiguration GetTenantConfig(string tenantId)
284274
{
285-
return new TenantConfiguration(new TestTenantConnectionProvider(Sfi, tenantId, IsSqlServerDialect));
275+
return new TestTenantConfiguration(tenantId, IsSqlServerDialect)
276+
{
277+
ConnectionString = Sfi.ConnectionProvider.GetConnectionString()
278+
};
286279
}
287280

288281
private bool IsSqlServerDialect => Sfi.Dialect is MsSql2000Dialect && !(Sfi.ConnectionProvider.Driver is OdbcDriver);
@@ -306,7 +299,8 @@ protected override HbmMapping GetMappings()
306299

307300
protected override DbConnection OpenConnectionForSchemaExport()
308301
{
309-
return GetTenantConfig("defaultTenant").ConnectionAccess.GetConnection();
302+
return Sfi.Settings.MultiTenancyConnectionProvider
303+
.GetConnectionAccess(GetTenantConfig("defaultTenant")).GetConnection(Sfi.ConnectionProvider);
310304
}
311305

312306
protected override ISession OpenSession()

src/NHibernate.Test/MultiTenancy/MockConnectionProvider.cs

-22
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System;
2+
using System.Data.SqlClient;
3+
using NHibernate.MultiTenancy;
4+
5+
namespace NHibernate.Test.MultiTenancy
6+
{
7+
[Serializable]
8+
public class TestMultiTenancyConnectionProvider : DefaultMultiTenancyConnectionProvider
9+
{
10+
protected override string GetTenantConnectionString(TenantConfiguration configuration)
11+
{
12+
return configuration is TestTenantConfiguration tenant && tenant.IsSqlServerDialect
13+
? new SqlConnectionStringBuilder(configuration.ConnectionString) {ApplicationName = configuration.TenantIdentifier}.ToString()
14+
: base.GetTenantConnectionString(configuration);
15+
}
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System;
2+
using NHibernate.MultiTenancy;
3+
4+
namespace NHibernate.Test.MultiTenancy
5+
{
6+
[Serializable]
7+
public class TestTenantConfiguration : TenantConfiguration
8+
{
9+
public TestTenantConfiguration(string tenantIdentifier, bool isSqlServerDialect) : base(tenantIdentifier)
10+
{
11+
IsSqlServerDialect = isSqlServerDialect;
12+
}
13+
14+
public bool IsSqlServerDialect { get; }
15+
}
16+
}

src/NHibernate.Test/MultiTenancy/TestTenantConnectionProvider.cs

-31
This file was deleted.

src/NHibernate/AdoNet/ConnectionManager.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ public DbConnection Close()
165165
if (_backupConnection != null)
166166
{
167167
_log.Warn("Backup connection was still defined at time of closing.");
168-
_connectionAccess.CloseConnection(_backupConnection);
168+
_connectionAccess.CloseConnection(_backupConnection, Factory.ConnectionProvider);
169169
_backupConnection = null;
170170
}
171171

@@ -222,7 +222,7 @@ public DbConnection Disconnect()
222222

223223
private void CloseConnection()
224224
{
225-
_connectionAccess.CloseConnection(_connection);
225+
_connectionAccess.CloseConnection(_connection, Factory.ConnectionProvider);
226226
_connection = null;
227227
}
228228

@@ -256,7 +256,7 @@ public DbConnection GetConnection()
256256
{
257257
if (_ownConnection)
258258
{
259-
_connection = _connectionAccess.GetConnection();
259+
_connection = _connectionAccess.GetConnection(Factory.ConnectionProvider);
260260
// Will fail if the connection is already enlisted in another transaction.
261261
// Probable case: nested transaction scope with connection auto-enlistment enabled.
262262
// That is an user error.

src/NHibernate/Async/AdoNet/ConnectionManager.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ async Task<DbConnection> InternalGetConnectionAsync()
6161
{
6262
if (_ownConnection)
6363
{
64-
_connection = await (_connectionAccess.GetConnectionAsync(cancellationToken)).ConfigureAwait(false);
64+
_connection = await (_connectionAccess.GetConnectionAsync(Factory.ConnectionProvider, cancellationToken)).ConfigureAwait(false);
6565
// Will fail if the connection is already enlisted in another transaction.
6666
// Probable case: nested transaction scope with connection auto-enlistment enabled.
6767
// That is an user error.

src/NHibernate/Async/Connection/IConnectionAccess.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@ namespace NHibernate.Connection
1717
public partial interface IConnectionAccess
1818
{
1919
//ObtainConnection in hibernate
20-
Task<DbConnection> GetConnectionAsync(CancellationToken cancellationToken);
20+
Task<DbConnection> GetConnectionAsync(IConnectionProvider provider, CancellationToken cancellationToken);
2121
}
2222
}

src/NHibernate/Async/Impl/NonContextualConnectionAccess.cs

+2-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
using System;
1212
using System.Data.Common;
1313
using NHibernate.Connection;
14-
using NHibernate.Engine;
1514

1615
namespace NHibernate.Impl
1716
{
@@ -20,13 +19,13 @@ namespace NHibernate.Impl
2019
partial class NonContextualConnectionAccess : IConnectionAccess
2120
{
2221

23-
public Task<DbConnection> GetConnectionAsync(CancellationToken cancellationToken)
22+
public Task<DbConnection> GetConnectionAsync(IConnectionProvider provider, CancellationToken cancellationToken)
2423
{
2524
if (cancellationToken.IsCancellationRequested)
2625
{
2726
return Task.FromCanceled<DbConnection>(cancellationToken);
2827
}
29-
return _factory.ConnectionProvider.GetConnectionAsync(cancellationToken);
28+
return provider.GetConnectionAsync(ConnectionString, cancellationToken);
3029
}
3130
}
3231
}

src/NHibernate/Async/MultiTenancy/AbstractMultiTenantConnectionProvider.cs src/NHibernate/Async/MultiTenancy/DefaultMultiTenancyConnectionProvider.cs

+5-6
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,25 @@
1111
using System;
1212
using System.Data.Common;
1313
using NHibernate.Connection;
14-
using NHibernate.Engine;
15-
using NHibernate.Util;
14+
using Environment = NHibernate.Cfg.Environment;
1615

1716
namespace NHibernate.MultiTenancy
1817
{
1918
using System.Threading.Tasks;
2019
using System.Threading;
21-
public abstract partial class AbstractMultiTenantConnectionProvider : IMultiTenantConnectionProvider
20+
public partial class DefaultMultiTenancyConnectionProvider : IMultiTenancyConnectionProvider
2221
{
2322
partial class ContextualConnectionAccess : IConnectionAccess
2423
{
2524

26-
public Task<DbConnection> GetConnectionAsync(CancellationToken cancellationToken)
25+
public Task<DbConnection> GetConnectionAsync(IConnectionProvider provider, CancellationToken cancellationToken)
2726
{
2827
if (cancellationToken.IsCancellationRequested)
2928
{
3029
return Task.FromCanceled<DbConnection>(cancellationToken);
3130
}
32-
return _factory.ConnectionProvider.GetConnectionAsync(ConnectionString, cancellationToken);
31+
return provider.GetConnectionAsync(ConnectionString, cancellationToken);
3332
}
34-
}
33+
}
3534
}
3635
}

src/NHibernate/Cfg/Environment.cs

+5
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,11 @@ public static string Version
391391
/// <seealso cref="MultiTenancyStrategy"/>
392392
public const string MultiTenancy = "multiTenancy";
393393

394+
/// <summary>
395+
/// Connection provider for given multi-tenancy strategy.
396+
/// </summary>
397+
public const string MultiTenancyConnectionProvider = "multiTenancy.connection.provider";
398+
394399
private static IBytecodeProvider BytecodeProviderInstance;
395400
private static bool EnableReflectionOptimizer;
396401

src/NHibernate/Cfg/Loquacious/DbIntegrationConfigurationProperties.cs

+6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using NHibernate.Driver;
55
using NHibernate.Exceptions;
66
using NHibernate.Linq.Visitors;
7+
using NHibernate.MultiTenancy;
78
using NHibernate.Transaction;
89

910
namespace NHibernate.Cfg.Loquacious
@@ -158,6 +159,11 @@ public MultiTenancy.MultiTenancyStrategy MultiTenancy
158159
set { configuration.SetProperty(Environment.MultiTenancy, value.ToString()); }
159160
}
160161

162+
public void MultiTenancyConnectionProvider<TProvider>() where TProvider : IMultiTenancyConnectionProvider
163+
{
164+
configuration.SetProperty(Environment.MultiTenancyConnectionProvider, typeof(TProvider).AssemblyQualifiedName);
165+
}
166+
161167
#endregion
162168
}
163169
}

src/NHibernate/Cfg/Settings.cs

+2
Original file line numberDiff line numberDiff line change
@@ -210,5 +210,7 @@ internal string GetFullCacheRegionName(string name)
210210
}
211211

212212
public MultiTenancyStrategy MultiTenancyStrategy { get; internal set; }
213+
214+
public IMultiTenancyConnectionProvider MultiTenancyConnectionProvider { get; internal set; }
213215
}
214216
}

0 commit comments

Comments
 (0)