注册服务
MediatR_Demo\Program.cs
// using MediatR;
// using MediatR_Demo.Repository.Context;
// ...
// var builder = WebApplication.CreateBuilder(args);
// builder.Services.AddControllers();
// ...
// 👇注册服务
builder.Services.AddMediatR(typeof(Program));
// ...
// var app = builder.Build();
// app.Run();
控制器依赖注入使用
MediatR_Demo\Controllers\MovieController.cs
// using MediatR;
// using MediatR_Demo.Application.Movies.Queries.GetMovie;
// using MediatR_Demo.Domain.DTOs.Requests.Movie;
// namespace MediatR_Demo.Controllers;
// [Route("api/[controller]")]
// [ApiController]
// public class MovieController : ControllerBase
// {
private readonly IMediator _mediator;
public MovieController(IMediator mediator)
{
_mediator = mediator;
}
// [HttpGet("/getmovies/{id}")]
// public async Task<IActionResult> GetMovie(long id)
// {
// 👇
var movie = await _mediator.Send(new GetMovieQuery(id));
// if (movie != null)
// {
// return Ok(movie);
// }
// return NotFound($"No movie in database with ID: {id}.");
// }
// }
IRequest,Handler的输入,也可以理解成订阅标识
MediatR_Demo\Application\Movies\Queries\GetMovie\GetMovieQuery.cs
// using MediatR;
// using MediatR_Demo.Domain.DTOs.Responses.Movie;
// namespace MediatR_Demo.Application.Movies.Queries.GetMovie;
// 👇
public class GetMovieQuery : IRequest<GetMovieDto>
{
public long? Id { get; set; }
public GetMovieQuery(long? id)
{
Id = id;
}
}
IRequestHandler,Handler实现
👇 👇
MediatR_Demo\Application\Movies\Queries\GetMovie\GetMovieQueryHandler.cs
// using MediatR;
// using MediatR_Demo.Domain.DTOs.Responses.Movie;
// using MediatR_Demo.Repository.Context;
// using Microsoft.EntityFrameworkCore;
// namespace MediatR_Demo.Application.Movies.Queries.GetMovie
// {
// 👇输入 👇输出
public class GetMovieQueryHandler : IRequestHandler<GetMovieQuery, GetMovieDto>
{
// private readonly ApplicationDbContext _dbContext;
// public GetMovieQueryHandler(ApplicationDbContext dbContext)
// {
// _dbContext = dbContext;
// }
// 👇 需要实现的方法
public async Task<GetMovieDto> Handle(GetMovieQuery request, CancellationToken cancellationToken)
// {
// var movie = await _dbContext.Movies.Where(x => x.Id == request.Id).FirstOrDefaultAsync();
// if (movie != null)
// {
// var movieItem = movie.MapTo();
// return movieItem;
// }
// return null;
}
}
// }
注意文件夹和文件名称
↓ ↓
MediatR_Demo\Application\Movies\Commands\CreateMovie\CreateMovieCommand.cs
MediatR_Demo\Application\Movies\Commands\CreateMovie\CreateUserCommandHandler.cs
MediatR_Demo\Application\Movies\Commands\CreateMovie\CreateMovieExtension.cs
↓ ↓
MediatR_Demo\Application\Movies\Queries\GetMovie\GetMovieQuery.cs`
MediatR_Demo\Application\Movies\Queries\GetMovie\GetMovieQueryHandler.cs`
MediatR_Demo\Application\Movies\Queries\GetMovie\GetMovieQueryExtensions.cs`
完整代码
using MediatR_Demo.Domain.DTOs.Responses.Movie;
using MediatR_Demo.Domain.Entities.Movie;
namespace MediatR_Demo.Application.Movies.Queries.GetMovie;
public static class GetMovieQueryExtensions
{
public static GetMovieDto MapTo(this Movie movie)
{
return new GetMovieDto
{
Id = movie.Id,
Title = movie.Title,
Description = movie.Description,
Genre = movie.Genre,
Rating = movie.Rating
};
}
}
using MediatR;
using MediatR_Demo.Domain.DTOs.Responses.Movie;
namespace MediatR_Demo.Application.Movies.Queries.GetMovie;
public class GetMovieQuery : IRequest<GetMovieDto>
{
public long? Id { get; set; }
public GetMovieQuery(long? id)
{
Id = id;
}
}
using MediatR;
using MediatR_Demo.Domain.DTOs.Responses.Movie;
using MediatR_Demo.Repository.Context;
using Microsoft.EntityFrameworkCore;
namespace MediatR_Demo.Application.Movies.Queries.GetMovie;
public class GetMovieQueryHandler : IRequestHandler<GetMovieQuery, GetMovieDto>
{
private readonly ApplicationDbContext _dbContext;
public GetMovieQueryHandler(ApplicationDbContext dbContext)
{
_dbContext = dbContext;
}
public async Task<GetMovieDto> Handle(
GetMovieQuery request,
CancellationToken cancellationToken
)
{
var movie = await _dbContext.Movies.Where(x => x.Id == request.Id).FirstOrDefaultAsync();
if (movie != null)
{
var movieItem = movie.MapTo();
return movieItem;
}
return null;
}
}
MediatR_Demo\Repository\Context\ApplicationDbContext.cs
using MediatR_Demo.Domain.Entities.Movie;
using Microsoft.EntityFrameworkCore;
namespace MediatR_Demo.Repository.Context
{
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
}
public DbSet<Movie> Movies { get; set; }
}
}
using MediatR;
using MediatR_Demo.Application.Movies.Commands.CreateMovie;
using MediatR_Demo.Application.Movies.Queries.GetMovie;
using MediatR_Demo.Application.Movies.Queries.GetMovies;
using MediatR_Demo.Domain.DTOs.Requests.Movie;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace MediatR_Demo.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class MovieController : ControllerBase
{
private readonly IMediator _mediator;
public MovieController(IMediator mediator)
{
_mediator = mediator;
}
[HttpGet]
public async Task<IActionResult> GetMovies()
{
var movies = await _mediator.Send(new GetMoviesQuery());
if (movies != null)
{
return Ok(movies);
}
return NotFound("No movies in database. Please add a movie first.");
}
[HttpGet("/getmovies/{id}")]
public async Task<IActionResult> GetMovie(long id)
{
var movie = await _mediator.Send(new GetMovieQuery(id));
if (movie != null)
{
return Ok(movie);
}
return NotFound($"No movie in database with ID: {id}.");
}
[HttpPost]
public async Task<IActionResult> CreateMovie([FromBody] CreateMovieRequest request)
{
var movie = await _mediator.Send(new CreateMovieCommand(
request.Title,
request.Description,
request.Genre,
request.Rating));
return Ok(movie);
}
}
}
using MediatR;
using MediatR_Demo.Domain.DTOs.Responses.Movie;
using MediatR_Demo.Repository.Context;
using Microsoft.EntityFrameworkCore;
namespace MediatR_Demo.Application.Movies.Queries.GetMovies
{
public class GetMoviesQueryHandler : IRequestHandler<GetMoviesQuery, IList<GetMovieDto>>
{
private readonly ApplicationDbContext _dbContext;
public GetMoviesQueryHandler(ApplicationDbContext dbContext)
{
_dbContext = dbContext;
}
public async Task<IList<GetMovieDto>> Handle(GetMoviesQuery request, CancellationToken cancellationToken)
{
var movies = await _dbContext.Movies.ToListAsync();
var movieList = new List<GetMovieDto>();
foreach (var movieItem in movies)
{
var movie = movieItem.MapTo();
movieList.Add(movie);
}
return movieList;
}
}
}
using MediatR;
using MediatR_Demo.Repository.Context;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddDbContext<ApplicationDbContext>(
options => options.UseSqlServer(builder.Configuration.GetConnectionString("Standard")));
builder.Services.AddMediatR(typeof(Program));
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
MediatR_Demo\Domain\Entities\Movie\Movie.cs
using MediatR_Demo.Core.Enums;
namespace MediatR_Demo.Domain.Entities.Movie
{
public class Movie
{
public Movie(string? title, string? description, MovieGenre? genre, int? rating)
{
Title = title;
Description = description;
Genre = genre;
Rating = rating;
}
public long Id { get; set; }
public string? Title { get; set; }
public string? Description { get; set; }
public MovieGenre? Genre { get; set; }
public int? Rating { get; set; }
}
}
MediatR_Demo\Domain\DTOs\Responses\Movie\GetMovieDto.cs
using MediatR_Demo.Core.Enums;
namespace MediatR_Demo.Domain.DTOs.Responses.Movie
{
public class GetMovieDto
{
public long Id { get; set; }
public string? Title { get; set; }
public string? Description { get; set; }
public MovieGenre? Genre { get; set; }
public int? Rating { get; set; }
}
}
MediatR_Demo\Domain\DTOs\Responses\Movie\CreateMovieDto.cs
namespace MediatR_Demo.Domain.DTOs.Responses.Movie
{
public class CreateMovieDto
{
public CreateMovieDto(long id)
{
Id = id;
}
public long Id { get; set; }
}
}
MediatR_Demo\Domain\DTOs\Requests\Movie\CreateMovieRequest.cs
using MediatR_Demo.Core.Enums;
namespace MediatR_Demo.Domain.DTOs.Requests.Movie
{
public class CreateMovieRequest
{
public string? Title { get; set; }
public string? Description { get; set; }
public MovieGenre? Genre { get; set; }
public int? Rating { get; set; }
}
}
namespace MediatR_Demo.Core.Enums
{
public enum MovieGenre
{
Action,
Comedy,
Drama,
Fantasy,
Horror,
Mystery,
Romance,
Thriller,
Western
}
}
using MediatR_Demo.Domain.DTOs.Responses.Movie;
using MediatR_Demo.Domain.Entities.Movie;
namespace MediatR_Demo.Application.Movies.Queries.GetMovies
{
public static class GetMoviesQueryExtensions
{
public static GetMovieDto MapTo(this Movie movie)
{
return new GetMovieDto
{
Id = movie.Id,
Title = movie.Title,
Description = movie.Description,
Genre = movie.Genre,
Rating = movie.Rating
};
}
}
}
using MediatR;
using MediatR_Demo.Domain.DTOs.Responses.Movie;
namespace MediatR_Demo.Application.Movies.Queries.GetMovies
{
public class GetMoviesQuery : IRequest<IList<GetMovieDto>>
{
}
}
using MediatR;
using MediatR_Demo.Domain.DTOs.Responses.Movie;
using MediatR_Demo.Repository.Context;
namespace MediatR_Demo.Application.Movies.Commands.CreateMovie
{
public class CreateUserCommandHandler : IRequestHandler<CreateMovieCommand, CreateMovieDto>
{
private readonly ApplicationDbContext _dbContext;
public CreateUserCommandHandler(ApplicationDbContext dbContext)
{
_dbContext = dbContext;
}
public async Task<CreateMovieDto> Handle(CreateMovieCommand request, CancellationToken cancellationToken)
{
var movie = request.CreateMovie();
await _dbContext.Movies.AddAsync(movie);
await _dbContext.SaveChangesAsync();
return new CreateMovieDto(movie.Id);
}
}
}
using MediatR_Demo.Domain.Entities.Movie;
namespace MediatR_Demo.Application.Movies.Commands.CreateMovie
{
public static class CreateUserCommandExtension
{
public static Movie CreateMovie(this CreateMovieCommand command)
{
var movie = new Movie
(
command.Title,
command.Description,
command.Genre,
command.Rating
);
return movie;
}
}
}
using MediatR;
using MediatR_Demo.Core.Enums;
using MediatR_Demo.Domain.DTOs.Responses.Movie;
namespace MediatR_Demo.Application.Movies.Commands.CreateMovie
{
public class CreateMovieCommand : IRequest<CreateMovieDto>
{
public CreateMovieCommand(
string? title,
string? description,
MovieGenre? genre,
int? rating)
{
Title = title;
Description = description;
Genre = genre;
Rating = rating;
}
public string? Title { get; set; }
public string? Description { get; set; }
public MovieGenre? Genre { get; set; }
public int? Rating { get; set; }
}
}
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MediatR" Version="10.0.1" />
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="10.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.6">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
</ItemGroup>
</Project>
{
"ConnectionStrings": {
"Standard": "Server=localhost;Database=mediatr-demo;Trusted_Connection=True;"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}