Add configuration type binding and implement database connection, disable NativeAOT.

Add: binding setting file items to `AppSettings` class so to provide DI access as `IOptions<OptixServeSettings>`.

Add: EF Core and DbContext to access database in services. This results in disabling NativeAOT due to poor supports for *pre-compiled query*, however many design are optimized for AOT for later re-adoption.

Add: `DesignTimeDbContextFactory` to support EF Core migrations in NativeAOT. (Kept for re-enabling AOT.)

Add: `DbInitializer` for ensuring database connecting in startup.

Add: `ConfigurationHelper.CreateDefaultBuilder()` to read configuration files in default locations. Note this method is currently ONLY used by `DesignTimeDbContextFactory`. Refactor is expected.

Add: `CommonErrorDto` for simple error message.

Add: `VersionEndpoint` ONLY for debugging and testing purpose. Verylikely to be removed in the future.

Other: many utilities and fixes easy to understand.

Note: EF Core migrations are excluded in the early development. Not expected to be added in version control before v1.0 beta.
This commit is contained in:
2025-07-09 12:17:25 +08:00
parent 6fd6c9f20d
commit 7cce413f79
14 changed files with 266 additions and 28 deletions

View File

@ -0,0 +1,21 @@
using Microsoft.EntityFrameworkCore;
using OptixServe.Core.Models;
namespace OptixServe.Core.Data;
public class AppDbContext(DbContextOptions options) : DbContext(options)
{
public DbSet<User> Users { get; set; } = null!;
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<User>(user =>
{
user.HasKey(u => u.Id);
});
modelBuilder.Entity<User>().HasData([
new() {Id = "1", UserName = "admin", Password = "admin12345"}
]);
}
}

View File

@ -0,0 +1,11 @@
namespace OptixServe.Core.Data;
public class DbInitializer(AppDbContext dbContext)
{
private readonly AppDbContext _context = dbContext;
public void Initialize()
{
_context.Database.EnsureCreated();
}
}

View File

@ -1,8 +1,15 @@
namespace OptixServe.Core.Models;
public enum PrivilegeGroup
{
Admin,
User,
}
public record User
{
public required string Id { get; set; }
public required string UserName { get; set; }
public required string Password { get; set; }
public string? Password { get; set; }
public PrivilegeGroup PrivilegeGroup { get; set; } = PrivilegeGroup.User;
}

View File

@ -6,4 +6,8 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.6" />
</ItemGroup>
</Project>

View File

@ -1,3 +1,4 @@
using OptixServe.Core.Data;
using OptixServe.Core.Models;
namespace OptixServe.Core.Services;
@ -5,21 +6,20 @@ namespace OptixServe.Core.Services;
public interface IUserService
{
IEnumerable<User> GetUsers();
User? GetUserById(string Id);
User? GetUserById(string id);
}
public class UserService : IUserService
public class UserService(AppDbContext dbContext) : IUserService
{
public User? GetUserById(string Id)
private readonly AppDbContext _dbContext = dbContext;
public User? GetUserById(string id)
{
throw new NotImplementedException();
return _dbContext.Users.FirstOrDefault(u => u.Id == id);
}
public IEnumerable<User> GetUsers()
{
return [
new() { Id = "1234", UserName = "xxx", Password = "pass1" },
new() { Id = "5678", UserName = "yyy", Password = "pass2" }
];
return _dbContext.Users.AsEnumerable();
}
}