Jimmy Bogard(jbogard) 作の jbogard/MediatR がめちゃくちゃいい感じです。めちゃくちゃいいのに、ぐぐってみても日本語で紹介された記事が皆無なのでここで紹介しておきたいと思います。
MediatR は、デザインパターンのひとつ、Mediator パターンの実装をサポートするライブラリです。 ASP.Net Core で MVC や Web API を実装していて、何も考えずにガリガリ書いていたらファットコントローラができちゃいました…というような失敗をこのライブラリを活用することで避けることができます。
Mediator パターンと併せて、考え方の背景として『単一責任の原則』と『CQRS』を理解しておくとよいでしょう。
どういうふうに使えるのかは jbogard/ContosoUniversityDotNetCore を見ると早いです。 Microsoft の定番サンプルアプリケーション Contoso University が、MediatR を活用して実装されています。
たとえば、”コース”の削除においてコントローラがやっているのはこれだけ:
namespace ContosoUniversity.Features.Courses
{
public class CoursesController : Controller
{
private readonly IMediator _mediator;
public CoursesController(IMediator mediator) => _mediator = mediator;
// ~省略~
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Delete(Delete.Command command)
{
await _mediator.Send(command);
return this.RedirectToActionJson(nameof(Index));
}
}
}
Mediatorオブジェクトに「削除コマンドが来たから、あとはよしなにやってくれ。」と言っているだけですね。
実際の削除の処理は別のところで、「削除コマンドはこう処理する。」と定義しています。
namespace ContosoUniversity.Features.Courses
{
public class Delete
{
// ~省略~
public class Command : IRequest
{
[Display(Name = "Number")]
public int Id { get; set; }
public string Title { get; set; }
public int Credits { get; set; }
[Display(Name = "Department")]
public string DepartmentName { get; set; }
}
public class CommandHandler : AsyncRequestHandler<Command>
{
private readonly SchoolContext _db;
public CommandHandler(SchoolContext db) => _db = db;
protected override async Task HandleCore(Command message)
{
var course = await _db.Courses.FindAsync(message.Id);
_db.Courses.Remove(course);
}
}
}
}
各クラスの内容はめちゃシンプルですね。
大規模なアプリケーションではどう使われているのかという例は、Microsoftがマイクロサービスアプリケーションの実装例として公開している dotnet-architecture/eShopOnContainers を参考にするとよいでしょう。
MediatR、オススメです。