求ASP.NET Core 2.0 WebAPI中CQRS模式的可运行实现示例链接
Hey there! As someone who's just getting started with CQRS in ASP.NET Core 2.0 WebAPI, I totally get how helpful a concrete, runnable example can be. Let me walk you through a simplified but functional implementation you can build right away:
First, create a new ASP.NET Core 2.0 WebAPI project using the .NET CLI:
dotnet new webapi -n CQRSDemo cd CQRSDemo
These interfaces will act as contracts for your commands (write operations) and queries (read operations):
Command Interfaces (Core/Commands/ICommand.cs)
public interface ICommand { // Marker interface for commands } public interface ICommandHandler<in TCommand> where TCommand : ICommand { Task HandleAsync(TCommand command); }
Query Interfaces (Core/Queries/IQuery.cs)
public interface IQuery<TResult> { // Marker interface for queries with a return type } public interface IQueryHandler<in TQuery, TResult> where TQuery : IQuery<TResult> { Task<TResult> HandleAsync(TQuery query); }
Let's build a simple user management scenario to demonstrate:
User Model (Core/Models/User.cs)
public class User { public Guid Id { get; set; } public string Name { get; set; } public string Email { get; set; } }
Create User Command (Features/Users/Commands/CreateUserCommand.cs)
public class CreateUserCommand : ICommand { public string Name { get; set; } public string Email { get; set; } } public class CreateUserCommandHandler : ICommandHandler<CreateUserCommand> { // For demo purposes, we'll use an in-memory list instead of a real DB private static readonly List<User> _users = new List<User>(); public Task HandleAsync(CreateUserCommand command) { _users.Add(new User { Id = Guid.NewGuid(), Name = command.Name, Email = command.Email }); return Task.CompletedTask; } }
Get User Query (Features/Users/Queries/GetUserQuery.cs)
public class GetUserQuery : IQuery<User> { public Guid UserId { get; set; } } public class GetUserQueryHandler : IQueryHandler<GetUserQuery, User> { private static readonly List<User> _users = new List<User>(); public Task<User> HandleAsync(GetUserQuery query) { var user = _users.FirstOrDefault(u => u.Id == query.UserId); return Task.FromResult(user); } }
Open Startup.cs and add the command/query handlers to the dependency injection container:
public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_0); // Register command handlers services.AddTransient<ICommandHandler<CreateUserCommand>, CreateUserCommandHandler>(); // Register query handlers services.AddTransient<IQueryHandler<GetUserQuery, User>, GetUserQueryHandler>(); }
Create a controller to expose the CQRS operations (Controllers/UsersController.cs):
[Route("api/[controller]")] [ApiController] public class UsersController : ControllerBase { private readonly ICommandHandler<CreateUserCommand> _createUserHandler; private readonly IQueryHandler<GetUserQuery, User> _getUserHandler; public UsersController( ICommandHandler<CreateUserCommand> createUserHandler, IQueryHandler<GetUserQuery, User> getUserHandler) { _createUserHandler = createUserHandler; _getUserHandler = getUserHandler; } [HttpPost] public async Task<IActionResult> CreateUser([FromBody] CreateUserCommand command) { await _createUserHandler.HandleAsync(command); return Ok("User created successfully"); } [HttpGet("{id}")] public async Task<IActionResult> GetUser(Guid id) { var query = new GetUserQuery { UserId = id }; var user = await _getUserHandler.HandleAsync(query); if (user == null) return NotFound("User not found"); return Ok(user); } }
- Start the project:
dotnet run
- Use Postman, curl, or any API client to test:
- Create User: Send a
POSTrequest tohttps://localhost:5001/api/userswith the JSON body:{ "Name": "John Doe", "Email": "john.doe@example.com" } - Get User: Send a
GETrequest tohttps://localhost:5001/api/users/{userId}(replace{userId}with the GUID returned in your in-memory list, or adjust the handler to return the first user for testing).
- Create User: Send a
Note for Production
This is a simplified example. In real-world scenarios, you'd:
- Use a proper database (like SQL Server with Entity Framework Core) instead of in-memory lists
- Consider using a library like MediatR to simplify command/query dispatching (avoids manually injecting every handler)
- Add validation, error handling, and logging layers
内容的提问来源于stack exchange,提问作者Mukil Deepthi

