52 lines
8.3 KiB
HTML
52 lines
8.3 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en" itemscope itemtype="https://schema.org/Article">
|
|
<head>
|
|
<script async src="https://www.googletagmanager.com/gtag/js?id=G-G9G5HP50VK"></script>
|
|
<script>window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments);}gtag('js',new Date());gtag('config','G-G9G5HP50VK');</script>
|
|
<meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<title>Building Maintainable .NET Applications with MediatR and VSA | Indotalent Blog</title>
|
|
<meta name="description" content="How MediatR enables CQRS within Vertical Slice Architecture. Pipeline behaviors for validation, logging, and transactions. Complete code examples." />
|
|
<meta name="robots" content="index, follow" />
|
|
<link rel="canonical" href="https://www.indotalent.com/blog/vsa-mediatr.html" />
|
|
<link rel="icon" type="image/x-icon" href="../favicon.ico" />
|
|
<script type="application/ld+json">{ "@context":"https://schema.org","@type":"Article","headline":"Building Maintainable .NET Applications with MediatR and VSA","author":{"@type":"Person","name":"go2ismail"},"datePublished":"2026-05-01","publisher":{"@type":"Organization","name":"Indotalent"}}</script>
|
|
<script type="application/ld+json">{ "@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{ "@type":"ListItem","position":1,"name":"Home","item":"https://www.indotalent.com/" },{ "@type":"ListItem","position":2,"name":"Blog","item":"https://www.indotalent.com/blog/" },{ "@type":"ListItem","position":3,"name":"MediatR and VSA","item":"https://www.indotalent.com/blog/vsa-mediatr.html" }]}</script>
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
|
|
<script>tailwind.config={theme:{extend:{colors:{brand:{50:'#fff7ed',100:'#ffedd5',200:'#fed7aa',300:'#fdba74',400:'#fb923c',500:'#f97316',600:'#ea580c',700:'#c2410c'}},fontFamily:{sans:['Inter','system-ui','sans-serif']}}}}</script>
|
|
<style>.nav-blur{backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px)}.gradient-text{background:linear-gradient(135deg,#f97316,#ea580c);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}.btn-primary{display:inline-flex;align-items:center;justify-content:center;background:linear-gradient(135deg,#f97316,#ea580c);color:#fff;font-weight:600;border-radius:12px;padding:12px 24px;transition:all 0.2s;box-shadow:0 4px 14px -4px rgba(249,115,22,0.35);text-decoration:none}.btn-primary:hover{transform:translateY(-1px);box-shadow:0 8px 20px -4px rgba(249,115,22,0.45)}article h2{font-size:1.5rem;font-weight:700;margin:1.75rem 0 0.75rem;color:#111827}article h3{font-size:1.15rem;font-weight:600;margin:1.5rem 0 0.5rem}article p{font-size:0.95rem;line-height:1.8;color:#4b5563;margin-bottom:1rem}article code{background:#f3f4f6;padding:2px 6px;border-radius:4px;font-size:0.85rem;color:#ea580c}article pre{background:#1f2937;color:#f9fafb;padding:16px;border-radius:10px;overflow-x:auto;margin:1rem 0;font-size:0.85rem;line-height:1.6}article ul{list-style:disc;padding-left:1.5rem;margin-bottom:1rem}article ul li{font-size:0.95rem;line-height:1.8;color:#4b5563}</style>
|
|
</head>
|
|
<body class="bg-white text-gray-900 antialiased">
|
|
<nav aria-label="Breadcrumb" class="pt-20 bg-white border-b border-gray-100"><div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-2.5"><ol class="flex items-center gap-1.5 text-xs text-gray-400"><li><a href="../index.html" class="hover:text-brand-500">Home</a></li><li><span class="text-gray-300">/</span></li><li><a href="index.html" class="hover:text-brand-500">Blog</a></li><li><span class="text-gray-300">/</span></li><li><span class="text-gray-600 font-medium">MediatR & VSA</span></li></ol></div></nav>
|
|
<nav class="fixed top-0 left-0 right-0 z-50 nav-blur bg-white/85 border-b border-gray-200/60"><div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"><div class="flex items-center justify-between h-16"><a href="../index.html" class="flex items-center gap-2.5"><img src="../img/logo-indotalent-dark.svg" alt="Indotalent" class="h-8 w-auto" /></a><div class="hidden lg:flex items-center gap-6"><a href="../index.html#products" class="text-sm font-medium text-gray-600 hover:text-brand-500">Products</a><a href="../for-beginners.html" class="text-sm font-medium text-gray-600 hover:text-brand-500">Beginners</a><a href="../for-freelancers.html" class="text-sm font-medium text-gray-600 hover:text-brand-500">Freelancers</a><a href="index.html" class="text-sm font-medium text-brand-600">Blog</a></div></div></div></nav>
|
|
<section class="pt-24 pb-10 lg:pt-32 lg:pb-12"><div class="max-w-3xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
<div class="flex items-center gap-2 mb-3"><span class="text-xs font-semibold bg-amber-50 text-amber-700 border border-amber-200 rounded-full px-2.5 py-0.5">VSA</span><span class="text-xs text-gray-400">May 2026 · 9 min read</span></div>
|
|
<h1 class="text-3xl sm:text-4xl font-extrabold text-gray-900 mb-4">Building Maintainable .NET Applications with MediatR and VSA</h1>
|
|
<div class="bg-green-50 border border-green-200 rounded-xl p-4 mb-8"><p class="text-sm text-green-800 font-semibold mb-1">TL;DR</p><p class="text-sm text-green-700">MediatR is the backbone of VSA in .NET. It implements the Mediator pattern with <code>IRequest<TResponse></code> and pipeline behaviors for cross-cutting concerns like validation, logging, and transactions.</p></div>
|
|
<article>
|
|
<p>MediatR is more than just a mediator library — it's the backbone of effective Vertical Slice Architecture in .NET. It implements the Mediator pattern with two key abstractions: <code>IRequest<TResponse></code> for commands/queries and <code>IRequestHandler<TRequest, TResponse></code> for their handlers.</p>
|
|
<h2>Commands, Queries, and CQRS</h2>
|
|
<p>In VSA, each feature slice exposes its API through MediatR. Commands (which mutate state) are separate from Queries (which read state). This is CQRS — Command Query Responsibility Segregation — and it maps naturally onto VSA. A <code>CreateOrderCommand</code> and its handler live in <code>Features/Orders/</code>. The handler uses EF Core to persist the order. A <code>GetOrderByIdQuery</code> also lives in the same folder, optimized for reads with EF Core's no-tracking queries.</p>
|
|
<h2>Pipeline Behaviors: Cross-Cutting Concerns</h2>
|
|
<p>MediatR's pipeline behaviors handle cross-cutting concerns without cluttering business logic. Logging, validation, and transaction management are implemented once as behaviors and applied to all handlers automatically:</p>
|
|
<pre>public class ValidationBehavior<TRequest, TResponse>
|
|
: IPipelineBehavior<TRequest, TResponse>
|
|
{
|
|
public async Task<TResponse> Handle(TRequest req,
|
|
RequestHandlerDelegate<TResponse> next, CancellationToken ct)
|
|
{
|
|
var validator = _validators.GetValidator<TRequest>();
|
|
if (validator != null) await validator.ValidateAsync(req, ct);
|
|
return await next();
|
|
}
|
|
}</pre>
|
|
<p>This keeps your handlers clean — they focus purely on business logic while behaviors handle the plumbing.</p>
|
|
<h2>Key Takeaways</h2>
|
|
<ul><li>MediatR provides the CQRS backbone for VSA feature slices</li><li>Pipeline behaviors eliminate duplicated cross-cutting code</li><li>Indotalent products ship with pre-configured MediatR pipelines</li></ul>
|
|
</article>
|
|
<div class="mt-10 p-6 bg-gradient-to-r from-orange-50 to-amber-50 border border-orange-200 rounded-2xl"><p class="text-sm text-gray-700 font-semibold mb-2">Explore VSA Products</p><p class="text-sm text-gray-600 mb-4">Every Indotalent product uses MediatR + VSA. Complete source code — $21 each.</p><a href="../index.html#products" class="btn-primary text-sm">Explore Products</a></div>
|
|
<div class="mt-6"><a href="index.html" class="text-sm text-brand-600 hover:text-brand-700">← Back to Blog</a></div>
|
|
</div></section>
|
|
<footer class="bg-white border-t border-gray-200"><div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-10"><div class="flex flex-col md:flex-row items-center justify-between gap-4"><a href="../index.html" class="flex items-center gap-2"><img src="../img/logo-indotalent-dark.svg" alt="Indotalent" class="h-5 w-auto" /></a><p class="text-xs text-gray-500">© 2024-2026 Indotalent. <span class="text-brand-500">♥</span> by go2ismail</p></div></div></footer>
|
|
</body>
|
|
</html> |