怪物奇妙物语

宇宙无敌超级美少男的怪物奇妙物语

首页 新随笔 联系 管理

MediatR的使用

注册服务

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`

完整代码

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
        };
    }
}

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;
    }
}


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\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; }
    }
}


MediatR_Demo\Controllers\MovieController.cs

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);
        }
    }
}

MediatR_Demo\Application\Movies\Queries\GetMovies\GetMoviesQueryHandler.cs

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;
        }
    }
}

MediatR_Demo\Program.cs

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; }
    }
}

MediatR_Demo\Core\Enums\MovieGenre.cs

namespace MediatR_Demo.Core.Enums
{
    public enum MovieGenre
    {
        Action,
        Comedy,
        Drama,
        Fantasy,
        Horror,
        Mystery,
        Romance,
        Thriller,
        Western
    }
}

MediatR_Demo\Application\Movies\Queries\GetMovies\GetMoviesQueryExtensions.cs

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
            };
        }
    }
}

MediatR_Demo\Application\Movies\Queries\GetMovies\GetMoviesQuery.cs

using MediatR;
using MediatR_Demo.Domain.DTOs.Responses.Movie;

namespace MediatR_Demo.Application.Movies.Queries.GetMovies
{
    public class GetMoviesQuery : IRequest<IList<GetMovieDto>>
    {
    }
}

MediatR_Demo\Application\Movies\Commands\CreateMovie\CreateUserCommandHandler.cs

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);
        }
    }
}

MediatR_Demo\Application\Movies\Commands\CreateMovie\CreateUserCommandExtension.cs

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;
        }
    }
}

MediatR_Demo\Application\Movies\Commands\CreateMovie\CreateMovieCommand.cs

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; }
    }
}

MediatR_Demo\MediatR_Demo.csproj

<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>

MediatR_Demo\appsettings.json

{
  "ConnectionStrings": {
    "Standard": "Server=localhost;Database=mediatr-demo;Trusted_Connection=True;"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*"
}

MediatR_Demo\appsettings.Development.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  }
}

posted on 2024-06-14 06:33  超级无敌美少男战士  阅读(19)  评论(0编辑  收藏  举报