From d347e27a709adc8d61f4080ef567c9d6eea17b79 Mon Sep 17 00:00:00 2001 From: Rick van Dam Date: Mon, 1 Apr 2024 22:46:08 +0200 Subject: [PATCH] generate stable database names and reuse container instance --- .../DataBaseNameGenerator.cs | 17 +++++++++++++++++ .../ServiceCollectionExtensions.cs | 1 + .../ServiceCollectionExtensions.cs | 4 +++- .../PostgreSqlDatabase.cs | 4 ++-- .../PostgreSqlDatabasePoolPolicy.cs | 6 ++++-- .../ServiceCollectionExtensions.cs | 5 ++++- TestExamplesDotnet/IDataBaseNameGenerator.cs | 6 ++++++ 7 files changed, 37 insertions(+), 6 deletions(-) create mode 100644 TestExamplesDotnet.EntityFrameworkCore/DataBaseNameGenerator.cs create mode 100644 TestExamplesDotnet/IDataBaseNameGenerator.cs diff --git a/TestExamplesDotnet.EntityFrameworkCore/DataBaseNameGenerator.cs b/TestExamplesDotnet.EntityFrameworkCore/DataBaseNameGenerator.cs new file mode 100644 index 0000000..d600102 --- /dev/null +++ b/TestExamplesDotnet.EntityFrameworkCore/DataBaseNameGenerator.cs @@ -0,0 +1,17 @@ +using Microsoft.EntityFrameworkCore; + +namespace TestExamplesDotnet; + +public sealed class DataBaseNameGenerator : IDataBaseNameGenerator + where TDbContext : DbContext +{ + private int _counter; + + public string GetDataBaseName() + { + var migrationId = typeof(TDbContext).Assembly.ManifestModule.ModuleVersionId.ToString("N");; + + var counter = Interlocked.Increment(ref _counter); + return $"{migrationId}_{counter}"; + } +} diff --git a/TestExamplesDotnet.EntityFrameworkCore/ServiceCollectionExtensions.cs b/TestExamplesDotnet.EntityFrameworkCore/ServiceCollectionExtensions.cs index bbc8b5e..0fad172 100644 --- a/TestExamplesDotnet.EntityFrameworkCore/ServiceCollectionExtensions.cs +++ b/TestExamplesDotnet.EntityFrameworkCore/ServiceCollectionExtensions.cs @@ -9,5 +9,6 @@ public static void RegisterMigrationInitializer(this IServiceCollectio where TContext : DbContext { services.AddTransient>(); + services.AddSingleton>(); } } diff --git a/TestExamplesDotnet.Mssql/ServiceCollectionExtensions.cs b/TestExamplesDotnet.Mssql/ServiceCollectionExtensions.cs index 7e86008..5a98759 100644 --- a/TestExamplesDotnet.Mssql/ServiceCollectionExtensions.cs +++ b/TestExamplesDotnet.Mssql/ServiceCollectionExtensions.cs @@ -16,7 +16,9 @@ public static void RegisterMssqlContainer(this IServiceCollection services) }); services.AddTransient, MsSqlDatabasePoolPolicy>(); - var container = new MsSqlBuilder().Build(); + var container = new MsSqlBuilder() + .WithReuse(true) + .Build(); Utils.RunWithoutSynchronizationContext(() => container.StartAsync().Wait()); services.AddSingleton(container); } diff --git a/TestExamplesDotnet.PostgreSql/PostgreSqlDatabase.cs b/TestExamplesDotnet.PostgreSql/PostgreSqlDatabase.cs index b1895b8..e310b31 100644 --- a/TestExamplesDotnet.PostgreSql/PostgreSqlDatabase.cs +++ b/TestExamplesDotnet.PostgreSql/PostgreSqlDatabase.cs @@ -13,11 +13,11 @@ public sealed class PostgreSqlDatabase : IDatabase private bool _initialized; public string ConnectionString { get; } - public PostgreSqlDatabase(PostgreSqlContainer container, IDatabaseInitializer databaseInitializer, RespawnerOptions respawnerOptions) + public PostgreSqlDatabase(PostgreSqlContainer container, IDatabaseInitializer databaseInitializer, RespawnerOptions respawnerOptions, IDataBaseNameGenerator dataBaseNameGenerator) { _databaseInitializer = databaseInitializer; _respawnerOptions = respawnerOptions; - ConnectionString = $"Host=127.0.0.1;Port={container.GetMappedPublicPort(5432)};Database={Guid.NewGuid()};Username=postgres;Password=postgres;Include Error Detail=true"; + ConnectionString = $"Host=127.0.0.1;Port={container.GetMappedPublicPort(5432)};Database={dataBaseNameGenerator.GetDataBaseName()};Username=postgres;Password=postgres;Include Error Detail=true"; } public void Initialize(IHost host) diff --git a/TestExamplesDotnet.PostgreSql/PostgreSqlDatabasePoolPolicy.cs b/TestExamplesDotnet.PostgreSql/PostgreSqlDatabasePoolPolicy.cs index 7f913a7..8c73816 100644 --- a/TestExamplesDotnet.PostgreSql/PostgreSqlDatabasePoolPolicy.cs +++ b/TestExamplesDotnet.PostgreSql/PostgreSqlDatabasePoolPolicy.cs @@ -9,16 +9,18 @@ public sealed class PostgreSqlDatabasePoolPolicy : IPooledObjectPolicy new PostgreSqlDatabase(_container, _databaseInitializer, _respawnerOptions); + public IDatabase Create() => new PostgreSqlDatabase(_container, _databaseInitializer, _respawnerOptions, _dataBaseNameGenerator); public bool Return(IDatabase obj) => true; } diff --git a/TestExamplesDotnet.PostgreSql/ServiceCollectionExtensions.cs b/TestExamplesDotnet.PostgreSql/ServiceCollectionExtensions.cs index c985c62..d48670d 100644 --- a/TestExamplesDotnet.PostgreSql/ServiceCollectionExtensions.cs +++ b/TestExamplesDotnet.PostgreSql/ServiceCollectionExtensions.cs @@ -16,8 +16,11 @@ public static void RegisterPostgreSqlContainer(this IServiceCollection services) }); services.AddTransient, PostgreSqlDatabasePoolPolicy>(); - var container = new PostgreSqlBuilder().Build(); + var container = new PostgreSqlBuilder() + .WithReuse(true) + .Build(); Utils.RunWithoutSynchronizationContext(() => container.StartAsync().Wait()); + services.AddSingleton(container); } } diff --git a/TestExamplesDotnet/IDataBaseNameGenerator.cs b/TestExamplesDotnet/IDataBaseNameGenerator.cs new file mode 100644 index 0000000..29f3e4f --- /dev/null +++ b/TestExamplesDotnet/IDataBaseNameGenerator.cs @@ -0,0 +1,6 @@ +namespace TestExamplesDotnet; + +public interface IDataBaseNameGenerator +{ + string GetDataBaseName(); +}