diff --git a/Directory.Build.props b/Directory.Build.props
index 85066f3..c74a237 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -1,4 +1,10 @@
+
+ net9.0
+ enable
+ enable
+
+
Copyright © 2015-2024 Petabridge
Petabridge
@@ -12,7 +18,4 @@
$(NoWarn);CS1591
-
- net8.0
-
\ No newline at end of file
diff --git a/Directory.Packages.props b/Directory.Packages.props
index ef5d59e..0182acb 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -12,20 +12,33 @@
-
-
-
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
-
-
-
-
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
diff --git a/DrawTogether.sln b/DrawTogether.sln
index 052d455..9a688d1 100644
--- a/DrawTogether.sln
+++ b/DrawTogether.sln
@@ -27,6 +27,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{DC3392A7
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DrawTogether.Tests", "tests\DrawTogether.Tests\DrawTogether.Tests.csproj", "{108B25F0-A606-47C6-9151-CB0095110DDC}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "aspire", "aspire", "{0C6E23C7-5F35-475D-85EF-3A3FE13D814A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DrawTogether.AppHost", "src\DrawTogether.AppHost\DrawTogether.AppHost.csproj", "{FB2F6129-90DA-4C6C-A318-D492DE6B3DCF}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DrawTogether.MigrationService", "src\DrawTogether.MigrationService\DrawTogether.MigrationService.csproj", "{2C615B52-0412-4FE2-B22C-5B1F7839F0AF}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -97,6 +103,30 @@ Global
{108B25F0-A606-47C6-9151-CB0095110DDC}.Release|x64.Build.0 = Release|Any CPU
{108B25F0-A606-47C6-9151-CB0095110DDC}.Release|x86.ActiveCfg = Release|Any CPU
{108B25F0-A606-47C6-9151-CB0095110DDC}.Release|x86.Build.0 = Release|Any CPU
+ {FB2F6129-90DA-4C6C-A318-D492DE6B3DCF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FB2F6129-90DA-4C6C-A318-D492DE6B3DCF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FB2F6129-90DA-4C6C-A318-D492DE6B3DCF}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {FB2F6129-90DA-4C6C-A318-D492DE6B3DCF}.Debug|x64.Build.0 = Debug|Any CPU
+ {FB2F6129-90DA-4C6C-A318-D492DE6B3DCF}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {FB2F6129-90DA-4C6C-A318-D492DE6B3DCF}.Debug|x86.Build.0 = Debug|Any CPU
+ {FB2F6129-90DA-4C6C-A318-D492DE6B3DCF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FB2F6129-90DA-4C6C-A318-D492DE6B3DCF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FB2F6129-90DA-4C6C-A318-D492DE6B3DCF}.Release|x64.ActiveCfg = Release|Any CPU
+ {FB2F6129-90DA-4C6C-A318-D492DE6B3DCF}.Release|x64.Build.0 = Release|Any CPU
+ {FB2F6129-90DA-4C6C-A318-D492DE6B3DCF}.Release|x86.ActiveCfg = Release|Any CPU
+ {FB2F6129-90DA-4C6C-A318-D492DE6B3DCF}.Release|x86.Build.0 = Release|Any CPU
+ {2C615B52-0412-4FE2-B22C-5B1F7839F0AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2C615B52-0412-4FE2-B22C-5B1F7839F0AF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2C615B52-0412-4FE2-B22C-5B1F7839F0AF}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {2C615B52-0412-4FE2-B22C-5B1F7839F0AF}.Debug|x64.Build.0 = Debug|Any CPU
+ {2C615B52-0412-4FE2-B22C-5B1F7839F0AF}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {2C615B52-0412-4FE2-B22C-5B1F7839F0AF}.Debug|x86.Build.0 = Debug|Any CPU
+ {2C615B52-0412-4FE2-B22C-5B1F7839F0AF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2C615B52-0412-4FE2-B22C-5B1F7839F0AF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2C615B52-0412-4FE2-B22C-5B1F7839F0AF}.Release|x64.ActiveCfg = Release|Any CPU
+ {2C615B52-0412-4FE2-B22C-5B1F7839F0AF}.Release|x64.Build.0 = Release|Any CPU
+ {2C615B52-0412-4FE2-B22C-5B1F7839F0AF}.Release|x86.ActiveCfg = Release|Any CPU
+ {2C615B52-0412-4FE2-B22C-5B1F7839F0AF}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -106,5 +136,6 @@ Global
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{108B25F0-A606-47C6-9151-CB0095110DDC} = {DC3392A7-58A4-4C8C-9401-6DDCD41FBF16}
+ {FB2F6129-90DA-4C6C-A318-D492DE6B3DCF} = {0C6E23C7-5F35-475D-85EF-3A3FE13D814A}
EndGlobalSection
EndGlobal
diff --git a/global.json b/global.json
index 0cfe4c8..3d8048a 100644
--- a/global.json
+++ b/global.json
@@ -1,6 +1,6 @@
{
"sdk": {
"rollForward": "latestMinor",
- "version": "8.0.101"
+ "version": "9.0.100"
}
}
\ No newline at end of file
diff --git a/src/DrawTogether.Actors/DrawTogether.Actors.csproj b/src/DrawTogether.Actors/DrawTogether.Actors.csproj
index 54ebfa9..84d45bc 100644
--- a/src/DrawTogether.Actors/DrawTogether.Actors.csproj
+++ b/src/DrawTogether.Actors/DrawTogether.Actors.csproj
@@ -1,11 +1,5 @@
-
- net8.0
- enable
- enable
-
-
diff --git a/src/DrawTogether.AppHost/DrawTogether.AppHost.csproj b/src/DrawTogether.AppHost/DrawTogether.AppHost.csproj
new file mode 100644
index 0000000..7f7845b
--- /dev/null
+++ b/src/DrawTogether.AppHost/DrawTogether.AppHost.csproj
@@ -0,0 +1,20 @@
+
+
+
+
+
+ Exe
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/DrawTogether.AppHost/Program.cs b/src/DrawTogether.AppHost/Program.cs
new file mode 100644
index 0000000..f660889
--- /dev/null
+++ b/src/DrawTogether.AppHost/Program.cs
@@ -0,0 +1,17 @@
+var builder = DistributedApplication.CreateBuilder(args);
+
+var sqlServer = builder.AddSqlServer("sql");
+
+var db = sqlServer.AddDatabase("DrawTogetherDb");
+
+var migrationService = builder.AddProject("MigrationService")
+ .WaitFor(db)
+ .WithReference(db);
+
+builder.AddProject("DrawTogether")
+ .WithReference(db, "DefaultConnection")
+ .WaitForCompletion(migrationService);
+
+builder
+ .Build()
+ .Run();
diff --git a/src/DrawTogether.AppHost/Properties/launchSettings.json b/src/DrawTogether.AppHost/Properties/launchSettings.json
new file mode 100644
index 0000000..48f3191
--- /dev/null
+++ b/src/DrawTogether.AppHost/Properties/launchSettings.json
@@ -0,0 +1,29 @@
+{
+ "$schema": "https://json.schemastore.org/launchsettings.json",
+ "profiles": {
+ "https": {
+ "commandName": "Project",
+ "dotnetRunMessages": true,
+ "launchBrowser": true,
+ "applicationUrl": "https://localhost:17142;http://localhost:15099",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development",
+ "DOTNET_ENVIRONMENT": "Development",
+ "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21049",
+ "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22281"
+ }
+ },
+ "http": {
+ "commandName": "Project",
+ "dotnetRunMessages": true,
+ "launchBrowser": true,
+ "applicationUrl": "http://localhost:15099",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development",
+ "DOTNET_ENVIRONMENT": "Development",
+ "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19227",
+ "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20048"
+ }
+ }
+ }
+}
diff --git a/src/DrawTogether.AppHost/appsettings.Development.json b/src/DrawTogether.AppHost/appsettings.Development.json
new file mode 100644
index 0000000..0c208ae
--- /dev/null
+++ b/src/DrawTogether.AppHost/appsettings.Development.json
@@ -0,0 +1,8 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ }
+}
diff --git a/src/DrawTogether.AppHost/appsettings.json b/src/DrawTogether.AppHost/appsettings.json
new file mode 100644
index 0000000..31c092a
--- /dev/null
+++ b/src/DrawTogether.AppHost/appsettings.json
@@ -0,0 +1,9 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning",
+ "Aspire.Hosting.Dcp": "Warning"
+ }
+ }
+}
diff --git a/src/DrawTogether.Email/DrawTogether.Email.csproj b/src/DrawTogether.Email/DrawTogether.Email.csproj
index 8d7ca2b..fac4f72 100644
--- a/src/DrawTogether.Email/DrawTogether.Email.csproj
+++ b/src/DrawTogether.Email/DrawTogether.Email.csproj
@@ -1,11 +1,5 @@
-
- net8.0
- enable
- enable
-
-
diff --git a/src/DrawTogether.Entities/DrawTogether.Entities.csproj b/src/DrawTogether.Entities/DrawTogether.Entities.csproj
index 6c4eb25..496ed8f 100644
--- a/src/DrawTogether.Entities/DrawTogether.Entities.csproj
+++ b/src/DrawTogether.Entities/DrawTogether.Entities.csproj
@@ -1,11 +1,5 @@
-
- net8.0
- enable
- enable
-
-
diff --git a/src/DrawTogether.MigrationService/DrawTogether.MigrationService.csproj b/src/DrawTogether.MigrationService/DrawTogether.MigrationService.csproj
new file mode 100644
index 0000000..3a486b1
--- /dev/null
+++ b/src/DrawTogether.MigrationService/DrawTogether.MigrationService.csproj
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/DrawTogether.MigrationService/Program.cs b/src/DrawTogether.MigrationService/Program.cs
new file mode 100644
index 0000000..e5cda5d
--- /dev/null
+++ b/src/DrawTogether.MigrationService/Program.cs
@@ -0,0 +1,11 @@
+using DrawTogether.Data;
+using DrawTogether.MigrationService;
+
+var builder = Host.CreateApplicationBuilder(args);
+
+builder.AddSqlServerDbContext("DrawTogetherDb");
+
+builder.Services.AddHostedService();
+
+var host = builder.Build();
+host.Run();
\ No newline at end of file
diff --git a/src/DrawTogether.MigrationService/Properties/launchSettings.json b/src/DrawTogether.MigrationService/Properties/launchSettings.json
new file mode 100644
index 0000000..63f5dac
--- /dev/null
+++ b/src/DrawTogether.MigrationService/Properties/launchSettings.json
@@ -0,0 +1,12 @@
+{
+ "$schema": "http://json.schemastore.org/launchsettings.json",
+ "profiles": {
+ "DrawTogether.MigrationService": {
+ "commandName": "Project",
+ "dotnetRunMessages": true,
+ "environmentVariables": {
+ "DOTNET_ENVIRONMENT": "Development"
+ }
+ }
+ }
+}
diff --git a/src/DrawTogether.MigrationService/Worker.cs b/src/DrawTogether.MigrationService/Worker.cs
new file mode 100644
index 0000000..343bbaa
--- /dev/null
+++ b/src/DrawTogether.MigrationService/Worker.cs
@@ -0,0 +1,55 @@
+using DrawTogether.Data;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Storage;
+
+namespace DrawTogether.MigrationService;
+
+public class Worker(
+ IServiceProvider serviceProvider,
+ IHostApplicationLifetime hostApplicationLifetime,
+ ILogger logger) : BackgroundService
+{
+ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
+ {
+ try
+ {
+ using var scope = serviceProvider.CreateScope();
+ var dbContext = scope.ServiceProvider.GetRequiredService();
+
+ await EnsureCreatedAsync(dbContext, stoppingToken);
+ await RunMigrationAsync(dbContext, stoppingToken);
+ }
+ catch (Exception ex)
+ {
+ logger.LogError(ex, "An error occurred while migrating the database");
+ }
+
+ hostApplicationLifetime.StopApplication();
+ }
+
+ private async Task EnsureCreatedAsync(ApplicationDbContext dbContext, CancellationToken cancellationToken)
+ {
+ var strategy = dbContext.Database.CreateExecutionStrategy();
+ var databaseCreator = dbContext.Database.GetService();
+
+ await strategy.ExecuteAsync(async ct =>
+ {
+ if (!await databaseCreator.ExistsAsync(ct))
+ {
+ await databaseCreator.CreateAsync(ct);
+ logger.LogInformation("Database created");
+ }
+ }, cancellationToken);
+ }
+
+ private async Task RunMigrationAsync(ApplicationDbContext dbContext, CancellationToken cancellationToken)
+ {
+ var strategy = dbContext.Database.CreateExecutionStrategy();
+ await strategy.ExecuteAsync(async ct =>
+ {
+ await dbContext.Database.MigrateAsync(ct);
+ logger.LogInformation("Database migrated");
+ }, cancellationToken);
+ }
+}
\ No newline at end of file
diff --git a/src/DrawTogether.MigrationService/appsettings.Development.json b/src/DrawTogether.MigrationService/appsettings.Development.json
new file mode 100644
index 0000000..b2dcdb6
--- /dev/null
+++ b/src/DrawTogether.MigrationService/appsettings.Development.json
@@ -0,0 +1,8 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.Hosting.Lifetime": "Information"
+ }
+ }
+}
diff --git a/src/DrawTogether.MigrationService/appsettings.json b/src/DrawTogether.MigrationService/appsettings.json
new file mode 100644
index 0000000..b2dcdb6
--- /dev/null
+++ b/src/DrawTogether.MigrationService/appsettings.json
@@ -0,0 +1,8 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.Hosting.Lifetime": "Information"
+ }
+ }
+}
diff --git a/src/DrawTogether/Config/AkkaConfiguration.cs b/src/DrawTogether/Config/AkkaConfiguration.cs
index 43e85a7..8e4dde5 100644
--- a/src/DrawTogether/Config/AkkaConfiguration.cs
+++ b/src/DrawTogether/Config/AkkaConfiguration.cs
@@ -23,7 +23,7 @@ public static IServiceCollection ConfigureAkka(this IServiceCollection services,
var connectionString = configuration.GetConnectionString("DefaultConnection");
if (connectionString is null)
- throw new Exception("DefaultConnection setting is missing");
+ throw new Exception("DefaultConnection ConnectionString is missing");
var roleName = ClusterConstants.DrawStateRoleName;
diff --git a/src/DrawTogether/DrawTogether.csproj b/src/DrawTogether/DrawTogether.csproj
index 2ffe154..906998b 100644
--- a/src/DrawTogether/DrawTogether.csproj
+++ b/src/DrawTogether/DrawTogether.csproj
@@ -1,9 +1,6 @@
- net8.0
- enable
- enable
aspnet-DrawTogether-519D8737-B9C5-4479-BE39-7C98C7D228C7
Linux
drawtogether-app
@@ -32,6 +29,7 @@
+
diff --git a/src/DrawTogether/Program.cs b/src/DrawTogether/Program.cs
index cf1411c..3592ece 100644
--- a/src/DrawTogether/Program.cs
+++ b/src/DrawTogether/Program.cs
@@ -42,9 +42,8 @@
})
.AddIdentityCookies();
-var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found.");
-builder.Services.AddDbContext(options =>
- options.UseSqlServer(connectionString));
+builder.AddSqlServerDbContext("DefaultConnection");
+
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddIdentityCore(options => options.SignIn.RequireConfirmedAccount = true)
diff --git a/src/DrawTogether/appsettings.json b/src/DrawTogether/appsettings.json
index 59b87d3..ebb3efc 100644
--- a/src/DrawTogether/appsettings.json
+++ b/src/DrawTogether/appsettings.json
@@ -1,7 +1,4 @@
{
- "ConnectionStrings": {
- "DefaultConnection": "Server=localhost,1633; Database=DrawTogether; User Id=sa; Password=yourStrong(!)Password; TrustServerCertificate=true;"
- },
"Logging": {
"LogLevel": {
"Default": "Information",
diff --git a/tests/DrawTogether.Tests/DrawTogether.Tests.csproj b/tests/DrawTogether.Tests/DrawTogether.Tests.csproj
index ffa3667..6e1e42c 100644
--- a/tests/DrawTogether.Tests/DrawTogether.Tests.csproj
+++ b/tests/DrawTogether.Tests/DrawTogether.Tests.csproj
@@ -1,10 +1,6 @@
- net8.0
- enable
- enable
-
false
true