Implement endpoints with Services Dependency Injection.

**Note: This implementation is not in minimalAPI way and not optimized, expected to be changed soon.**

Add: `UserService` and its interface `IUserService`.

Fix: `UserEndpoint` is now in instance class style with DI to work.

Fix: change main program to work with above design.
This commit is contained in:
2025-07-07 15:54:44 +08:00
parent 1e4aaf33f9
commit 39b28386ae
3 changed files with 84 additions and 30 deletions

View File

@ -1,4 +1,5 @@
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using OptixServe.Core.Services;
using OptixServe.Api.Dtos; using OptixServe.Api.Dtos;
namespace OptixServe.Api.Endpoints; namespace OptixServe.Api.Endpoints;
@ -8,25 +9,37 @@ namespace OptixServe.Api.Endpoints;
[JsonSerializable(typeof(IEnumerable<UserDto>))] [JsonSerializable(typeof(IEnumerable<UserDto>))]
public partial class UserJsonContext : JsonSerializerContext { } public partial class UserJsonContext : JsonSerializerContext { }
public static class UserEndpoint public class UserEndpoint
{ {
public static IEnumerable<UserDto> GetUsers() private readonly IUserService _userService;
// 通过构造函数注入依赖
public UserEndpoint(IUserService userService)
{ {
return [ _userService = userService;
new() {Id="1234", UserName = "xxx"},
new() {Id="5678", UserName = "yyy"},
];
} }
public static void Register(WebApplication app) public static void Register(WebApplication app)
{ {
var group = app.MapGroup("/users"); var group = app.MapGroup("/users");
group.MapGet("/", GetAllUsers); group.MapGet("/", (UserEndpoint endpoint) => endpoint.GetAllUsers());
group.MapGet("/{id}", (string id, UserEndpoint endpoint) => endpoint.GetUserById(id));
} }
public static IResult GetAllUsers() public IResult GetAllUsers()
{ {
return Results.Ok(GetUsers()); var users = _userService.GetUsers()
.Select(u => new UserDto { Id = u.Id, UserName = u.UserName });
return Results.Ok(users);
}
public IResult GetUserById(string id)
{
var user = _userService.GetUserById(id);
if (user == null)
return Results.NotFound();
return Results.Ok(new UserDto { Id = user.Id, UserName = user.UserName });
} }
} }

View File

@ -1,5 +1,6 @@
using System.CommandLine; using System.CommandLine;
using OptixServe.Api.Endpoints; using OptixServe.Api.Endpoints;
using OptixServe.Core.Services;
class Program class Program
{ {
@ -41,6 +42,7 @@ class Program
var configFile = parseResult.GetValue(configOption); var configFile = parseResult.GetValue(configOption);
builder.AddConfigurationWithCommand(configFile); builder.AddConfigurationWithCommand(configFile);
builder.RegisterServices();
builder.RegiserJsonContext(); builder.RegiserJsonContext();
var app = builder.Build(); var app = builder.Build();
@ -61,27 +63,6 @@ class Program
/// </summary> /// </summary>
static class ExtensionMethods static class ExtensionMethods
{ {
/// <summary>
/// Registers all API endpoints
/// </summary>
/// <param name="app">WebApplication instance</param>
public static void RegisterEndpoints(this WebApplication app)
{
UserEndpoint.Register(app);
}
/// <summary>
/// Configures JSON serialization options with custom context
/// </summary>
/// <param name="builder">WebApplicationBuilder instance</param>
public static void RegiserJsonContext(this WebApplicationBuilder builder)
{
builder.Services.ConfigureHttpJsonOptions(options =>
{
options.SerializerOptions.TypeInfoResolverChain.Add(UserJsonContext.Default);
});
}
/// <summary> /// <summary>
/// Adds configuration sources to the application builder /// Adds configuration sources to the application builder
/// </summary> /// </summary>
@ -105,4 +86,39 @@ static class ExtensionMethods
builder.Configuration.AddConfiguration(configurationBuilder.Build()); builder.Configuration.AddConfiguration(configurationBuilder.Build());
} }
/// <summary>
/// Configures JSON serialization options with custom context
/// </summary>
/// <param name="builder">WebApplicationBuilder instance</param>
public static void RegiserJsonContext(this WebApplicationBuilder builder)
{
builder.Services.ConfigureHttpJsonOptions(options =>
{
options.SerializerOptions.TypeInfoResolverChain.Add(UserJsonContext.Default);
});
}
/// <summary>
/// Configures services for DI
/// </summary>
/// <param name="builder"></param>
public static void RegisterServices(this WebApplicationBuilder builder)
{
// Application services
builder.Services.AddScoped<IUserService, UserService>();
// WebAPI Endpoint services
builder.Services.AddScoped<UserEndpoint>();
}
/// <summary>
/// Registers all API endpoints
/// </summary>
/// <param name="app">WebApplication instance</param>
public static void RegisterEndpoints(this WebApplication app)
{
UserEndpoint.Register(app);
}
} }

View File

@ -0,0 +1,25 @@
using OptixServe.Core.Models;
namespace OptixServe.Core.Services;
public interface IUserService
{
IEnumerable<User> GetUsers();
User? GetUserById(string Id);
}
public class UserService : IUserService
{
public User? GetUserById(string Id)
{
throw new NotImplementedException();
}
public IEnumerable<User> GetUsers()
{
return [
new() { Id = "1234", UserName = "xxx", Password = "pass1" },
new() { Id = "5678", UserName = "yyy", Password = "pass2" }
];
}
}