Compare commits
	
		
			2 Commits
		
	
	
		
			a21cd0cea2
			...
			dec6cfd65c
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| dec6cfd65c | |||
| 8b18de1735 | 
| @ -1,16 +1,15 @@ | |||||||
| namespace OptixServe.Api.Configuration; | namespace OptixServe.Api.Configuration; | ||||||
| 
 | 
 | ||||||
| public record OptixServeSettings | public record ApiConfiguration | ||||||
| { | { | ||||||
|     public ApiSettings? Api { get; set; } = new(); |     public ApiSettings? Api { get; set; } = new(); | ||||||
|     public DatabaseSettings? Database { get; set; } = new(); |  | ||||||
|     public JwtSettings? Jwt { get; set; } = new(); |     public JwtSettings? Jwt { get; set; } = new(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| public record ApiSettings | public record ApiSettings | ||||||
| { | { | ||||||
|     public string? Listen { get; set; } = "127.0.0.1"; |     public string? Listen { get; set; } | ||||||
|     public int? Port { get; set; } = 10086; |     public int? Port { get; set; } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| public record JwtSettings | public record JwtSettings | ||||||
| @ -20,15 +19,3 @@ public record JwtSettings | |||||||
|     public string Audience { get; set; } = "OptixServeUsers"; |     public string Audience { get; set; } = "OptixServeUsers"; | ||||||
|     public int TokenExpirationMinutes { get; set; } = 60; |     public int TokenExpirationMinutes { get; set; } = 60; | ||||||
| } | } | ||||||
| 
 |  | ||||||
| public enum DatabaseType |  | ||||||
| { |  | ||||||
|     Sqlite, |  | ||||||
|     MySQL |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| public record DatabaseSettings |  | ||||||
| { |  | ||||||
|     public DatabaseType Type { get; set; } = DatabaseType.Sqlite; |  | ||||||
|     public string? Host { get; set; } |  | ||||||
| } |  | ||||||
| @ -1,8 +1,7 @@ | |||||||
| using System.Text.Json.Serialization; | using System.Text.Json.Serialization; | ||||||
| using OptixServe.Core.Services; | using OptixServe.Application.Services; | ||||||
| using OptixServe.Api.Dtos; | using OptixServe.Api.Dtos; | ||||||
| using OptixServe.Api.Services; | using OptixServe.Api.Services; | ||||||
| using Microsoft.AspNetCore.Authorization; |  | ||||||
|  |  | ||||||
| namespace OptixServe.Api.Endpoints; | namespace OptixServe.Api.Endpoints; | ||||||
|  |  | ||||||
| @ -10,7 +9,7 @@ namespace OptixServe.Api.Endpoints; | |||||||
| [JsonSerializable(typeof(UserDto))] | [JsonSerializable(typeof(UserDto))] | ||||||
| [JsonSerializable(typeof(IEnumerable<UserDto>))] | [JsonSerializable(typeof(IEnumerable<UserDto>))] | ||||||
| [JsonSerializable(typeof(LoginRequestDto))] | [JsonSerializable(typeof(LoginRequestDto))] | ||||||
| [JsonSerializable(typeof(LoginResponseDto))] // For returning the token string | [JsonSerializable(typeof(LoginResponseDto))] | ||||||
| public partial class UserJsonContext : JsonSerializerContext { } | public partial class UserJsonContext : JsonSerializerContext { } | ||||||
|  |  | ||||||
| public static class UserEndpoint | public static class UserEndpoint | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| using System.Text.Json.Serialization; | using System.Text.Json.Serialization; | ||||||
| using Microsoft.Extensions.Options; | using Microsoft.Extensions.Options; | ||||||
| using OptixServe.Api.Configuration; | using OptixServe.Infrastructure.Configuration; | ||||||
| using OptixServe.Api.Dtos; | using OptixServe.Api.Dtos; | ||||||
|  |  | ||||||
| namespace OptixServe.Api.Endpoints; | namespace OptixServe.Api.Endpoints; | ||||||
| @ -22,10 +22,10 @@ public static class VersionEndpoint | |||||||
|         var group = parentGroup.MapGroup("/version"); |         var group = parentGroup.MapGroup("/version"); | ||||||
|  |  | ||||||
|         group.MapGet("/", () => "v1"); |         group.MapGet("/", () => "v1"); | ||||||
|         group.MapGet("/test/dbconfig", (IOptions<OptixServeSettings> appSettings) => |         group.MapGet("/test/dbconfig", (IOptions<InfrastructureConfiguration> infrastructureConfig) => | ||||||
|         { |         { | ||||||
|             var dbType = appSettings.Value.Database?.Type; |             var dbType = infrastructureConfig.Value.Database?.Type; | ||||||
|             var dbHost = appSettings.Value.Database?.Host; |             var dbHost = infrastructureConfig.Value.Database?.Host; | ||||||
|             return Results.Ok(new CommonErrorDto |             return Results.Ok(new CommonErrorDto | ||||||
|             { |             { | ||||||
|                 Message = $"Set up {dbType} database on {dbHost}" |                 Message = $"Set up {dbType} database on {dbHost}" | ||||||
|  | |||||||
| @ -2,16 +2,13 @@ | |||||||
|  |  | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <ProjectReference Include="..\OptixServe.Core\OptixServe.Core.csproj" /> |     <ProjectReference Include="..\OptixServe.Core\OptixServe.Core.csproj" /> | ||||||
|  |     <ProjectReference Include="..\OptixServe.Application\OptixServe.Application.csproj" /> | ||||||
|  |     <ProjectReference Include="..\OptixServe.Infrastructure\OptixServe.Infrastructure.csproj" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|  |  | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.6" /> |     <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.6" /> | ||||||
|     <PackageReference Include="System.CommandLine" Version="2.0.0-beta5.25306.1" /> |     <PackageReference Include="System.CommandLine" Version="2.0.0-beta5.25306.1" /> | ||||||
|     <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.6"> |  | ||||||
|       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> |  | ||||||
|       <PrivateAssets>all</PrivateAssets> |  | ||||||
|     </PackageReference> |  | ||||||
|     <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.6" /> |  | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|  |  | ||||||
|   <PropertyGroup> |   <PropertyGroup> | ||||||
|  | |||||||
| @ -5,9 +5,10 @@ using Microsoft.IdentityModel.Tokens; | |||||||
| using OptixServe.Api.Configuration; | using OptixServe.Api.Configuration; | ||||||
| using OptixServe.Api.Endpoints; | using OptixServe.Api.Endpoints; | ||||||
| using OptixServe.Api.Services; | using OptixServe.Api.Services; | ||||||
| using OptixServe.Core.Data; | using OptixServe.Application.Services; | ||||||
| using OptixServe.Core.Services; | using OptixServe.Infrastructure.Configuration; | ||||||
| using OptixServe.Api.Utilites; | using OptixServe.Infrastructure.Data; | ||||||
|  | using OptixServe.Infrastructure.Utilites; | ||||||
|  |  | ||||||
| class Program | class Program | ||||||
| { | { | ||||||
| @ -89,12 +90,7 @@ static class StartupHelper | |||||||
|     public static void AddConfigurationWithCommand(this WebApplicationBuilder builder, FileInfo? file) |     public static void AddConfigurationWithCommand(this WebApplicationBuilder builder, FileInfo? file) | ||||||
|     { |     { | ||||||
|         // Configure configuration sources in specified order |         // Configure configuration sources in specified order | ||||||
|         var configurationBuilder = new ConfigurationBuilder() |         var configurationBuilder = ConfigurationHelper.CreateDefaultBuilder(); | ||||||
|             .SetBasePath(Directory.GetCurrentDirectory()) |  | ||||||
|             .AddJsonFile("appsettings.json", optional: true) |  | ||||||
|             .AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", optional: true) |  | ||||||
|             .AddJsonFile("config.json", optional: true) |  | ||||||
|             .AddJsonFile($"config.{builder.Environment.EnvironmentName}.json", optional: true); |  | ||||||
|  |  | ||||||
|         // Add command-line specified config file if provided |         // Add command-line specified config file if provided | ||||||
|         if (file != null) |         if (file != null) | ||||||
| @ -123,13 +119,17 @@ static class StartupHelper | |||||||
|     /// <param name="builder">WebApplicationBuilder instance</param> |     /// <param name="builder">WebApplicationBuilder instance</param> | ||||||
|     public static void RegisterServices(this WebApplicationBuilder builder) |     public static void RegisterServices(this WebApplicationBuilder builder) | ||||||
|     { |     { | ||||||
|         // Add configuration class |         // Add configuration classes | ||||||
|         var optixSettigns = builder.Configuration.GetSection("OptixServe"); |         var apiConfigSection = builder.Configuration.GetSection("OptixServe:Api"); | ||||||
|         var onConfigSettings = optixSettigns.Get<OptixServeSettings>(); |         builder.Services.Configure<ApiConfiguration>(apiConfigSection); | ||||||
|         builder.Services.Configure<OptixServeSettings>(optixSettigns); |         var apiConfig = apiConfigSection.Get<ApiConfiguration>(); | ||||||
|  |  | ||||||
|  |         var infraConfigSection = builder.Configuration.GetSection("OptixServe:Infrastructure"); | ||||||
|  |         builder.Services.Configure<InfrastructureConfiguration>(infraConfigSection); | ||||||
|  |         var infraConfig = infraConfigSection.Get<InfrastructureConfiguration>(); | ||||||
|  |  | ||||||
|         // Add DBContext class |         // Add DBContext class | ||||||
|         builder.Services.AddAppDatabase(onConfigSettings?.Database!); |         builder.Services.AddAppDatabase(infraConfig?.Database!); | ||||||
|         builder.Services.AddScoped<DbInitializer>(); |         builder.Services.AddScoped<DbInitializer>(); | ||||||
|  |  | ||||||
|         // Application services |         // Application services | ||||||
| @ -140,7 +140,7 @@ static class StartupHelper | |||||||
|         builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) |         builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) | ||||||
|             .AddJwtBearer(options => |             .AddJwtBearer(options => | ||||||
|             { |             { | ||||||
|                 var jwtSettings = onConfigSettings?.Jwt ?? throw new ArgumentNullException(nameof(builder), "JWT settings are not configured."); |                 var jwtSettings = apiConfig?.Jwt ?? throw new ArgumentNullException(nameof(builder), "JWT settings are not configured."); | ||||||
|                 options.TokenValidationParameters = new TokenValidationParameters |                 options.TokenValidationParameters = new TokenValidationParameters | ||||||
|                 { |                 { | ||||||
|                     ValidateIssuer = true, |                     ValidateIssuer = true, | ||||||
|  | |||||||
| @ -13,9 +13,9 @@ public interface ITokenService | |||||||
|     public string GenerateToken(User user); |     public string GenerateToken(User user); | ||||||
| } | } | ||||||
|  |  | ||||||
| public class TokenService(IOptions<OptixServeSettings> optixServeSettings) : ITokenService | public class TokenService(IOptions<ApiConfiguration> apiConfiguration) : ITokenService | ||||||
| { | { | ||||||
|     private readonly JwtSettings _jwtSettings = optixServeSettings.Value.Jwt ?? throw new ArgumentNullException(nameof(optixServeSettings), "JWT settings are not configured."); |     private readonly JwtSettings _jwtSettings = apiConfiguration.Value.Jwt ?? throw new ArgumentNullException(nameof(apiConfiguration), "JWT settings are not configured."); | ||||||
|  |  | ||||||
|     public string GenerateToken(User user) |     public string GenerateToken(User user) | ||||||
|     { |     { | ||||||
|  | |||||||
| @ -1,20 +0,0 @@ | |||||||
| using Microsoft.EntityFrameworkCore; |  | ||||||
| using Microsoft.EntityFrameworkCore.Design; |  | ||||||
| using OptixServe.Api.Configuration; |  | ||||||
| using OptixServe.Core.Data; |  | ||||||
|  |  | ||||||
| namespace OptixServe.Api.Utilites; |  | ||||||
|  |  | ||||||
| public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<AppDbContext> |  | ||||||
| { |  | ||||||
|     public AppDbContext CreateDbContext(string[] args) |  | ||||||
|     { |  | ||||||
|         var configuration = ConfigurationHelper.CreateDefaultBuilder().Build(); |  | ||||||
|  |  | ||||||
|         var dbSettings = configuration.GetSection("OptixServe:Database").Get<DatabaseSettings>()!; |  | ||||||
|         var optionsBuilder = new DbContextOptionsBuilder<AppDbContext>(); |  | ||||||
|         DatabaseHelper.ConfigureDbContext(optionsBuilder, dbSettings); |  | ||||||
|  |  | ||||||
|         return new AppDbContext(optionsBuilder.Options); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -9,17 +9,19 @@ | |||||||
|   "OptixServe": { |   "OptixServe": { | ||||||
|     "Api": { |     "Api": { | ||||||
|       "Listen": "0.0.0.0", |       "Listen": "0.0.0.0", | ||||||
|       "Port": "54321" |       "Port": "54321", | ||||||
|     }, |  | ||||||
|     "Database": { |  | ||||||
|       "Type": "Sqlite", |  | ||||||
|       "Host": "optixserve.db" |  | ||||||
|     }, |  | ||||||
|       "Jwt": { |       "Jwt": { | ||||||
|         "Secret": "YOUR_SECRET_KEY_HERE_DO_NOT_SHARE_THIS_AND_MAKE_IT_LONG_ENOUGH", |         "Secret": "YOUR_SECRET_KEY_HERE_DO_NOT_SHARE_THIS_AND_MAKE_IT_LONG_ENOUGH", | ||||||
|         "Issuer": "OptixServe", |         "Issuer": "OptixServe", | ||||||
|         "Audience": "OptixServeUsers", |         "Audience": "OptixServeUsers", | ||||||
|         "TokenExpirationMinutes": 60 |         "TokenExpirationMinutes": 60 | ||||||
|       } |       } | ||||||
|  |     }, | ||||||
|  |     "Infrastructure": { | ||||||
|  |       "Database": { | ||||||
|  |         "Type": "Sqlite", | ||||||
|  |         "Host": "optixserve.db" | ||||||
|  |       } | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
							
								
								
									
										18
									
								
								OptixServe.Application/OptixServe.Application.csproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								OptixServe.Application/OptixServe.Application.csproj
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | |||||||
|  | <Project Sdk="Microsoft.NET.Sdk"> | ||||||
|  |  | ||||||
|  |   <ItemGroup> | ||||||
|  |     <ProjectReference Include="..\OptixServe.Core\OptixServe.Core.csproj" /> | ||||||
|  |     <ProjectReference Include="..\OptixServe.Infrastructure\OptixServe.Infrastructure.csproj" /> | ||||||
|  |   </ItemGroup> | ||||||
|  |  | ||||||
|  |   <ItemGroup> | ||||||
|  |     <PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.6" /> | ||||||
|  |   </ItemGroup> | ||||||
|  |  | ||||||
|  |   <PropertyGroup> | ||||||
|  |     <TargetFramework>net9.0</TargetFramework> | ||||||
|  |     <ImplicitUsings>enable</ImplicitUsings> | ||||||
|  |     <Nullable>enable</Nullable> | ||||||
|  |   </PropertyGroup> | ||||||
|  |  | ||||||
|  | </Project> | ||||||
| @ -1,7 +1,7 @@ | |||||||
| using OptixServe.Core.Data; |  | ||||||
| using OptixServe.Core.Models; | using OptixServe.Core.Models; | ||||||
|  | using OptixServe.Infrastructure.Data; | ||||||
| 
 | 
 | ||||||
| namespace OptixServe.Core.Services; | namespace OptixServe.Application.Services; | ||||||
| 
 | 
 | ||||||
| public interface IUserService | public interface IUserService | ||||||
| { | { | ||||||
| @ -6,8 +6,5 @@ | |||||||
|     <Nullable>enable</Nullable> |     <Nullable>enable</Nullable> | ||||||
|   </PropertyGroup> |   </PropertyGroup> | ||||||
|  |  | ||||||
|   <ItemGroup> |  | ||||||
|     <PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.6" /> |  | ||||||
|   </ItemGroup> |  | ||||||
|  |  | ||||||
| </Project> | </Project> | ||||||
|  | |||||||
| @ -1,18 +1,18 @@ | |||||||
| using System; | using Microsoft.Extensions.Configuration; | ||||||
| 
 | 
 | ||||||
| namespace OptixServe.Api.Configuration; | namespace OptixServe.Infrastructure.Configuration; | ||||||
| 
 | 
 | ||||||
| public static class ConfigurationHelper | public static class ConfigurationHelper | ||||||
| { | { | ||||||
|     public static IConfigurationBuilder CreateDefaultBuilder() |     public static IConfigurationBuilder CreateDefaultBuilder(string basePath) | ||||||
|     { |     { | ||||||
|         var aspEnv = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"); |         var aspEnv = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"); | ||||||
|         var netEnv = Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT"); |         var netEnv = Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT"); | ||||||
|         // Console.WriteLine($"ASPNETCORE_ENVIRONMENT: {aspEnv}, DOTNET_ENVIRONMENT: {netEnv}"); |  | ||||||
|         var env = aspEnv ?? netEnv ?? null; |         var env = aspEnv ?? netEnv ?? null; | ||||||
| 
 | 
 | ||||||
|         var builder = new ConfigurationBuilder() |         var builder = new ConfigurationBuilder() | ||||||
|             .SetBasePath(Directory.GetCurrentDirectory()) |             // .SetBasePath(Directory.GetCurrentDirectory()) | ||||||
|  |             .SetBasePath(basePath) | ||||||
|             .AddJsonFile("appsettings.json", optional: true) |             .AddJsonFile("appsettings.json", optional: true) | ||||||
|             .AddJsonFile("config.json", optional: true); |             .AddJsonFile("config.json", optional: true); | ||||||
|          |          | ||||||
| @ -24,4 +24,9 @@ public static class ConfigurationHelper | |||||||
| 
 | 
 | ||||||
|         return builder; |         return builder; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     public static IConfigurationBuilder CreateDefaultBuilder() | ||||||
|  |     { | ||||||
|  |         return CreateDefaultBuilder(Directory.GetCurrentDirectory()); | ||||||
|  |     } | ||||||
| } | } | ||||||
| @ -0,0 +1,18 @@ | |||||||
|  | namespace OptixServe.Infrastructure.Configuration; | ||||||
|  |  | ||||||
|  | public record InfrastructureConfiguration | ||||||
|  | { | ||||||
|  |     public DatabaseSettings? Database { get; set; } = new(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | public enum DatabaseType | ||||||
|  | { | ||||||
|  |     Sqlite, | ||||||
|  |     MySQL | ||||||
|  | } | ||||||
|  |  | ||||||
|  | public record DatabaseSettings | ||||||
|  | { | ||||||
|  |     public DatabaseType Type { get; set; } = DatabaseType.Sqlite; | ||||||
|  |     public string? Host { get; set; } | ||||||
|  | } | ||||||
| @ -1,7 +1,7 @@ | |||||||
| using Microsoft.EntityFrameworkCore; | using Microsoft.EntityFrameworkCore; | ||||||
| using OptixServe.Core.Models; | using OptixServe.Core.Models; | ||||||
| 
 | 
 | ||||||
| namespace OptixServe.Core.Data; | namespace OptixServe.Infrastructure.Data; | ||||||
| 
 | 
 | ||||||
| public class AppDbContext(DbContextOptions options) : DbContext(options) | public class AppDbContext(DbContextOptions options) : DbContext(options) | ||||||
| { | { | ||||||
| @ -1,4 +1,4 @@ | |||||||
| namespace OptixServe.Core.Data; | namespace OptixServe.Infrastructure.Data; | ||||||
| 
 | 
 | ||||||
| public class DbInitializer(AppDbContext dbContext) | public class DbInitializer(AppDbContext dbContext) | ||||||
| { | { | ||||||
							
								
								
									
										2
									
								
								OptixServe.Infrastructure/Migrations/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								OptixServe.Infrastructure/Migrations/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,2 @@ | |||||||
|  | # Migrations are ignored in development | ||||||
|  | *.cs | ||||||
							
								
								
									
										25
									
								
								OptixServe.Infrastructure/OptixServe.Infrastructure.csproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								OptixServe.Infrastructure/OptixServe.Infrastructure.csproj
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | |||||||
|  | <Project Sdk="Microsoft.NET.Sdk"> | ||||||
|  |  | ||||||
|  |   <ItemGroup> | ||||||
|  |     <ProjectReference Include="..\OptixServe.Core\OptixServe.Core.csproj" /> | ||||||
|  |   </ItemGroup> | ||||||
|  |  | ||||||
|  |   <ItemGroup> | ||||||
|  |     <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.6"> | ||||||
|  |       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||||||
|  |       <PrivateAssets>all</PrivateAssets> | ||||||
|  |     </PackageReference> | ||||||
|  |     <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.6" /> | ||||||
|  |     <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="9.0.6" /> | ||||||
|  |     <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="9.0.6" /> | ||||||
|  |     <PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="9.0.6" /> | ||||||
|  |     <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.6" /> | ||||||
|  |   </ItemGroup> | ||||||
|  |  | ||||||
|  |   <PropertyGroup> | ||||||
|  |     <TargetFramework>net9.0</TargetFramework> | ||||||
|  |     <ImplicitUsings>enable</ImplicitUsings> | ||||||
|  |     <Nullable>enable</Nullable> | ||||||
|  |   </PropertyGroup> | ||||||
|  |  | ||||||
|  | </Project> | ||||||
| @ -1,8 +1,7 @@ | |||||||
| using Microsoft.EntityFrameworkCore; | using Microsoft.EntityFrameworkCore; | ||||||
| using OptixServe.Api.Configuration; | using OptixServe.Infrastructure.Configuration; | ||||||
| using OptixServe.Core.Data; |  | ||||||
| 
 | 
 | ||||||
| namespace OptixServe.Api.Utilites; | namespace OptixServe.Infrastructure.Utilites; | ||||||
| 
 | 
 | ||||||
| public static class DatabaseHelper | public static class DatabaseHelper | ||||||
| { | { | ||||||
| @ -23,7 +22,7 @@ public static class DatabaseHelper | |||||||
|             var dbPath = dbSettings.Host ?? "optixserve.db"; |             var dbPath = dbSettings.Host ?? "optixserve.db"; | ||||||
|             var connectionString = $"Data Source={dbPath}"; |             var connectionString = $"Data Source={dbPath}"; | ||||||
| 
 | 
 | ||||||
|             options.UseSqlite(connectionString, b => b.MigrationsAssembly("OptixServe.Api")); |             options.UseSqlite(connectionString, b => b.MigrationsAssembly("OptixServe.Infrastructure")); | ||||||
| 
 | 
 | ||||||
|         } |         } | ||||||
|         else |         else | ||||||
							
								
								
									
										129
									
								
								OptixServe.Infrastructure/Utilites/DesignTimeDbContextFactory.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								OptixServe.Infrastructure/Utilites/DesignTimeDbContextFactory.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,129 @@ | |||||||
|  | using Microsoft.EntityFrameworkCore; | ||||||
|  | using Microsoft.EntityFrameworkCore.Design; | ||||||
|  | using Microsoft.Extensions.Configuration; | ||||||
|  | using OptixServe.Infrastructure.Configuration; | ||||||
|  | using OptixServe.Infrastructure.Data; | ||||||
|  |  | ||||||
|  | namespace OptixServe.Infrastructure.Utilites; | ||||||
|  |  | ||||||
|  | public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<AppDbContext> | ||||||
|  | { | ||||||
|  |     private record CommandParseResult | ||||||
|  |     { | ||||||
|  |         public string? ConfigPath { get; set; } = null; | ||||||
|  |         public string? DataDir { get; set; } = null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private static CommandParseResult ParseArgs(string[] args) | ||||||
|  |     { | ||||||
|  |         var result = new CommandParseResult(); | ||||||
|  |         bool configSet = false; | ||||||
|  |         bool dataDirSet = false; | ||||||
|  |  | ||||||
|  |         for (int i = 0; i < args.Length; i++) | ||||||
|  |         { | ||||||
|  |             string arg = args[i]; | ||||||
|  |  | ||||||
|  |             if (arg == "--config" || arg == "-c") | ||||||
|  |             { | ||||||
|  |                 if (configSet) | ||||||
|  |                 { | ||||||
|  |                     throw new ArgumentException("The --config/-c option can only be specified once."); | ||||||
|  |                 } | ||||||
|  |                 if (i + 1 >= args.Length) | ||||||
|  |                 { | ||||||
|  |                     throw new ArgumentException("Missing value for --config/-c option."); | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 result.ConfigPath = args[i + 1]; | ||||||
|  |                 configSet = true; | ||||||
|  |                 i++; | ||||||
|  |             } | ||||||
|  |             else if (arg == "--data-dir" || arg == "-d") | ||||||
|  |             { | ||||||
|  |                 if (dataDirSet) | ||||||
|  |                 { | ||||||
|  |                     throw new ArgumentException("The --data-dir/-d option can only be specified once."); | ||||||
|  |                 } | ||||||
|  |                 if (i + 1 >= args.Length) | ||||||
|  |                 { | ||||||
|  |                     throw new ArgumentException("Missing value for --data-dir/-d option."); | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 result.DataDir = args[i + 1]; | ||||||
|  |                 dataDirSet = true; | ||||||
|  |                 i++; | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 throw new ArgumentException($"Unknown argument: {arg}"); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return result; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// <summary> | ||||||
|  |     /// Creates DbContext instance in Design-Time | ||||||
|  |     ///  | ||||||
|  |     /// <para>Custom arguments should be passed in <i>dotnet</i> command </para> | ||||||
|  |     ///  | ||||||
|  |     /// <b>Example:</b><br/> | ||||||
|  |     /// <example><c>dotnet ef database update -- -c ../data/appsettings.Development.json -d ../data/`</c></example> | ||||||
|  |     ///  | ||||||
|  |     /// </summary> | ||||||
|  |     /// <param name="args"> | ||||||
|  |     ///     <list type="bullet"> | ||||||
|  |     ///         <item> | ||||||
|  |     ///             --config/-c: App configuration file to load with database connection settings. | ||||||
|  |     ///         </item> | ||||||
|  |     ///         <item> | ||||||
|  |     ///             --data-dir/-d: App data dir to work with. | ||||||
|  |     ///             Currently this only affects finding SQLite database when relative path | ||||||
|  |     ///             is specified in database settings. | ||||||
|  |     ///         </item> | ||||||
|  |     ///     </list> | ||||||
|  |     /// </param> | ||||||
|  |     /// <returns></returns> | ||||||
|  |     public AppDbContext CreateDbContext(string[] args) | ||||||
|  |     { | ||||||
|  |         var parsedArgs = ParseArgs(args); | ||||||
|  |  | ||||||
|  |         IConfigurationRoot configuration; | ||||||
|  |  | ||||||
|  |         if (!string.IsNullOrEmpty(parsedArgs.ConfigPath)) | ||||||
|  |         { | ||||||
|  |             var absConfigPath = Path.GetFullPath(parsedArgs.ConfigPath); | ||||||
|  |             var configDirectory = Path.GetDirectoryName(absConfigPath); | ||||||
|  |             var configFileName = Path.GetFileName(absConfigPath); | ||||||
|  |             // Use the provided config file path | ||||||
|  |             configuration = new ConfigurationBuilder() | ||||||
|  |                 .SetBasePath(configDirectory ?? "") | ||||||
|  |                 .AddJsonFile(configFileName, optional: false) | ||||||
|  |                 .Build(); | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             // Default search configuration path | ||||||
|  |             configuration = ConfigurationHelper.CreateDefaultBuilder().Build(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         var dbSettings = configuration.GetSection("OptixServe:Infrastructure:Database").Get<DatabaseSettings>()!; | ||||||
|  |  | ||||||
|  |         // Resolve SQLite database if `--data-dir` is specified and `dbSettings.Host` is relative | ||||||
|  |         if (parsedArgs.DataDir != null) | ||||||
|  |         { | ||||||
|  |             if (dbSettings.Type == DatabaseType.Sqlite && !Path.IsPathFullyQualified(dbSettings.Host!)) | ||||||
|  |             { | ||||||
|  |                 var dbRelPath = Path.Combine(parsedArgs.DataDir, dbSettings.Host!); | ||||||
|  |                 var dbAbsPath = Path.GetFullPath(dbRelPath); | ||||||
|  |                 dbSettings.Host = dbAbsPath; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         var optionsBuilder = new DbContextOptionsBuilder<AppDbContext>(); | ||||||
|  |         DatabaseHelper.ConfigureDbContext(optionsBuilder, dbSettings); | ||||||
|  |  | ||||||
|  |         return new AppDbContext(optionsBuilder.Options); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -7,6 +7,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OptixServe.Core", "OptixSer | |||||||
| EndProject | EndProject | ||||||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OptixServe.Api", "OptixServe.Api\OptixServe.Api.csproj", "{52559B29-A255-4BDC-8F2B-A984DEE69E7E}" | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OptixServe.Api", "OptixServe.Api\OptixServe.Api.csproj", "{52559B29-A255-4BDC-8F2B-A984DEE69E7E}" | ||||||
| EndProject | EndProject | ||||||
|  | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OptixServe.Infrastructure", "OptixServe.Infrastructure\OptixServe.Infrastructure.csproj", "{E90B4BE9-BCE3-48AC-B60E-1ADF2D328408}" | ||||||
|  | EndProject | ||||||
|  | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OptixServe.Application", "OptixServe.Application\OptixServe.Application.csproj", "{71D84B31-775B-4EF8-9D0B-411A8CE1CC3A}" | ||||||
|  | EndProject | ||||||
| Global | Global | ||||||
| 	GlobalSection(SolutionConfigurationPlatforms) = preSolution | 	GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||||
| 		Debug|Any CPU = Debug|Any CPU | 		Debug|Any CPU = Debug|Any CPU | ||||||
| @ -41,6 +45,30 @@ Global | |||||||
| 		{52559B29-A255-4BDC-8F2B-A984DEE69E7E}.Release|x64.Build.0 = Release|Any CPU | 		{52559B29-A255-4BDC-8F2B-A984DEE69E7E}.Release|x64.Build.0 = Release|Any CPU | ||||||
| 		{52559B29-A255-4BDC-8F2B-A984DEE69E7E}.Release|x86.ActiveCfg = Release|Any CPU | 		{52559B29-A255-4BDC-8F2B-A984DEE69E7E}.Release|x86.ActiveCfg = Release|Any CPU | ||||||
| 		{52559B29-A255-4BDC-8F2B-A984DEE69E7E}.Release|x86.Build.0 = Release|Any CPU | 		{52559B29-A255-4BDC-8F2B-A984DEE69E7E}.Release|x86.Build.0 = Release|Any CPU | ||||||
|  | 		{E90B4BE9-BCE3-48AC-B60E-1ADF2D328408}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||||||
|  | 		{E90B4BE9-BCE3-48AC-B60E-1ADF2D328408}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||||
|  | 		{E90B4BE9-BCE3-48AC-B60E-1ADF2D328408}.Debug|x64.ActiveCfg = Debug|Any CPU | ||||||
|  | 		{E90B4BE9-BCE3-48AC-B60E-1ADF2D328408}.Debug|x64.Build.0 = Debug|Any CPU | ||||||
|  | 		{E90B4BE9-BCE3-48AC-B60E-1ADF2D328408}.Debug|x86.ActiveCfg = Debug|Any CPU | ||||||
|  | 		{E90B4BE9-BCE3-48AC-B60E-1ADF2D328408}.Debug|x86.Build.0 = Debug|Any CPU | ||||||
|  | 		{E90B4BE9-BCE3-48AC-B60E-1ADF2D328408}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||||||
|  | 		{E90B4BE9-BCE3-48AC-B60E-1ADF2D328408}.Release|Any CPU.Build.0 = Release|Any CPU | ||||||
|  | 		{E90B4BE9-BCE3-48AC-B60E-1ADF2D328408}.Release|x64.ActiveCfg = Release|Any CPU | ||||||
|  | 		{E90B4BE9-BCE3-48AC-B60E-1ADF2D328408}.Release|x64.Build.0 = Release|Any CPU | ||||||
|  | 		{E90B4BE9-BCE3-48AC-B60E-1ADF2D328408}.Release|x86.ActiveCfg = Release|Any CPU | ||||||
|  | 		{E90B4BE9-BCE3-48AC-B60E-1ADF2D328408}.Release|x86.Build.0 = Release|Any CPU | ||||||
|  | 		{71D84B31-775B-4EF8-9D0B-411A8CE1CC3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||||||
|  | 		{71D84B31-775B-4EF8-9D0B-411A8CE1CC3A}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||||
|  | 		{71D84B31-775B-4EF8-9D0B-411A8CE1CC3A}.Debug|x64.ActiveCfg = Debug|Any CPU | ||||||
|  | 		{71D84B31-775B-4EF8-9D0B-411A8CE1CC3A}.Debug|x64.Build.0 = Debug|Any CPU | ||||||
|  | 		{71D84B31-775B-4EF8-9D0B-411A8CE1CC3A}.Debug|x86.ActiveCfg = Debug|Any CPU | ||||||
|  | 		{71D84B31-775B-4EF8-9D0B-411A8CE1CC3A}.Debug|x86.Build.0 = Debug|Any CPU | ||||||
|  | 		{71D84B31-775B-4EF8-9D0B-411A8CE1CC3A}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||||||
|  | 		{71D84B31-775B-4EF8-9D0B-411A8CE1CC3A}.Release|Any CPU.Build.0 = Release|Any CPU | ||||||
|  | 		{71D84B31-775B-4EF8-9D0B-411A8CE1CC3A}.Release|x64.ActiveCfg = Release|Any CPU | ||||||
|  | 		{71D84B31-775B-4EF8-9D0B-411A8CE1CC3A}.Release|x64.Build.0 = Release|Any CPU | ||||||
|  | 		{71D84B31-775B-4EF8-9D0B-411A8CE1CC3A}.Release|x86.ActiveCfg = Release|Any CPU | ||||||
|  | 		{71D84B31-775B-4EF8-9D0B-411A8CE1CC3A}.Release|x86.Build.0 = Release|Any CPU | ||||||
| 	EndGlobalSection | 	EndGlobalSection | ||||||
| 	GlobalSection(SolutionProperties) = preSolution | 	GlobalSection(SolutionProperties) = preSolution | ||||||
| 		HideSolutionNode = FALSE | 		HideSolutionNode = FALSE | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user