<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Akash Lomas</title>
    <description>The latest articles on DEV Community by Akash Lomas (@akash_lomas_ns).</description>
    <link>https://dev.to/akash_lomas_ns</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3865207%2F45a56a44-9dcd-4ee0-a726-e330af8be434.png</url>
      <title>DEV Community: Akash Lomas</title>
      <link>https://dev.to/akash_lomas_ns</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/akash_lomas_ns"/>
    <language>en</language>
    <item>
      <title>SDLC to ADLC</title>
      <dc:creator>Akash Lomas</dc:creator>
      <pubDate>Mon, 06 Jul 2026 05:01:42 +0000</pubDate>
      <link>https://dev.to/akash_lomas_ns/sdlc-to-adlc-1lk3</link>
      <guid>https://dev.to/akash_lomas_ns/sdlc-to-adlc-1lk3</guid>
      <description>&lt;p&gt;Enterprise software development is undergoing a fundamental structural shift. For decades, the traditional Software Development Life Cycle (SDLC) relied on human engineers writing deterministic code. Today, code generation is increasingly shifted to autonomous AI agents.&lt;/p&gt;

&lt;p&gt;According to the &lt;em&gt;McKinsey State of AI&lt;/em&gt; report, &lt;strong&gt;78 percent of organizations&lt;/strong&gt; have integrated AI into at least one business function. This operational shift is mirrored at the developer level; the &lt;em&gt;2026 Stack Overflow Developer Survey&lt;/em&gt; indicates that &lt;strong&gt;84 percent of engineers&lt;/strong&gt; now utilize or plan to deploy AI tools.&lt;/p&gt;

&lt;p&gt;For initial baseline tasks—such as boilerplate code, standard API integrations, and basic scaffolding—the efficiency gains remain clear. GitHub data shows that developers complete these isolated tasks &lt;strong&gt;55 percent faster&lt;/strong&gt; when utilizing basic AI coding assistants.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;The Pull Request Bottleneck&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The core complication stems from integrating high-velocity AI generation tools into legacy, human-centric review workflows. This structural mismatch has shifted the engineering bottleneck from code production to code verification.&lt;/p&gt;

&lt;p&gt;Data from software delivery platform LinearB reveals that while organizations face a &lt;strong&gt;2X or greater increase in pull request (PR) volume&lt;/strong&gt;, net engineering productivity gains remain in the low double digits. Senior engineers now has to spend disproportionate time auditing vast volumes of AI-generated code rather than designing system architecture.&lt;/p&gt;

&lt;p&gt;Furthermore, standard AI tools frequently fail during the "last 40 percent" of the development cycle, which includes complex system integration, scalability testing, and non-functional requirements.&lt;/p&gt;

&lt;p&gt;Consequently, an Atlan study projects that &lt;strong&gt;over 40 percent of agentic AI initiatives will face cancellation by 2027&lt;/strong&gt; due to context gaps and inadequate methodology. McKinsey data confirms these execution failures, tracing them directly to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A lack of clear specifications:&lt;/strong&gt; 61 percent of failed implementations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data quality issues:&lt;/strong&gt; 55 percent&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An absence of governance frameworks:&lt;/strong&gt; 48 percent&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;The Scaling Dilemma&lt;/strong&gt;
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;How can enterprise engineering organizations transition from isolated, developer-centric AI assistants to an operating model that scales autonomous execution without introducing architectural debt, overwhelming human reviewers, or incurring unsustainable inference costs?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Transitioning to the Agentic Development Life Cycle (ADLC)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The industry's emerging resolution is the &lt;strong&gt;Agentic Development Life Cycle (ADLC)&lt;/strong&gt;—an architecture that replaces sequential human handoffs with multi-agent AI networks operating across a continuous layer of shared context. This structural shift eliminates legacy queues that traditionally consume &lt;strong&gt;60 to 70 percent of a project’s calendar time&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;The Core Framework Shifts&lt;/strong&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Role Reconfiguration:&lt;/strong&gt; Engineers transition from line-by-line syntax writers to intent architects who define environmental boundaries, security constraints, and success criteria.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Specification-Driven Engineering:&lt;/strong&gt; Teams utilize frameworks like SPARC (Situation, Problem, Action, Result, Constraints). Because agents execute exactly what is specified, precision in the initial product requirement document dictates output quality.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Distribution-Based Evaluation:&lt;/strong&gt; Because agent outputs are probabilistic rather than deterministic, traditional binary pass/fail testing is replaced by automated evaluation harnesses that measure code quality consistency across thousands of parallel simulations.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Adoption Patterns and Market Realities&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;The corporate landscape is currently divided between AI-native startups and legacy incumbents retrofitting their workflows. Gartner and McKinsey data indicates that early adopters are deploying parallel sub-agents to manage testing, build infrastructure, and automate canary deployments.&lt;/p&gt;

&lt;p&gt;However, systemic execution remains rare. McKinsey notes that only &lt;strong&gt;6 percent of organizations&lt;/strong&gt; qualify as AI "high performers" (deriving over 5 percent of EBIT from AI). These leaders are &lt;strong&gt;three times more likely&lt;/strong&gt; to have fundamentally re-engineered their operational workflows rather than simply adding tools to legacy SDLC structures.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;The Operational Balance Sheet&lt;/strong&gt;
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;The Targeted ROI&lt;/strong&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Compressed Time-to-Market:&lt;/strong&gt; ADLC delivery teams compress traditional 4-to-6-month MVP timelines down to &lt;strong&gt;6 to 8 weeks&lt;/strong&gt;, representing a &lt;strong&gt;60 percent reduction&lt;/strong&gt; in overall calendar time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Direct Cost Reduction:&lt;/strong&gt; Full agentic integration lowers total project expenses by &lt;strong&gt;40 to 65 percent&lt;/strong&gt;, driven by a &lt;strong&gt;75 percent reduction&lt;/strong&gt; in manual coding time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Early Defect Prevention:&lt;/strong&gt; Generating automated test scripts directly from the requirements stage makes defect remediation &lt;strong&gt;5X to 10X cheaper&lt;/strong&gt; than fixing bugs during post-development QA.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;The Accompanying Risks&lt;/strong&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Novel Governance Hazards:&lt;/strong&gt; McKinsey reports that &lt;strong&gt;12 percent of AI agent deployments&lt;/strong&gt; introduce entirely new technical risks, including recursive execution loops, prompt injections, and authorization drift.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Logic Inaccuracy:&lt;/strong&gt; Code hallucinations remain a persistent factor, with &lt;strong&gt;33 percent of enterprise AI users&lt;/strong&gt; experiencing logic errors that bypassed unguided agent systems.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Escalating Inference Costs:&lt;/strong&gt; Multi-agent cognitive loops significantly increase token consumption, risking budget overruns comparable to early cloud migration miscalculations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Regulatory Compliance:&lt;/strong&gt; Under frameworks like the EU AI Act, companies must maintain a &lt;strong&gt;100 percent auditable trail&lt;/strong&gt; of an agent's reasoning steps, tool interactions, and data origins.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;** What is your opinion on this? **&lt;/p&gt;

</description>
      <category>sdlc</category>
      <category>ai</category>
      <category>architecture</category>
      <category>agentskills</category>
    </item>
    <item>
      <title>Architectural Collapse: How Extension Poisoning, Node Vulnerabilities, and Infrastructure Fog Enabled the GitHub Repository Breach</title>
      <dc:creator>Akash Lomas</dc:creator>
      <pubDate>Mon, 25 May 2026 07:22:24 +0000</pubDate>
      <link>https://dev.to/akash_lomas_ns/architectural-collapse-how-extension-poisoning-node-vulnerabilities-and-infrastructure-fog-i84</link>
      <guid>https://dev.to/akash_lomas_ns/architectural-collapse-how-extension-poisoning-node-vulnerabilities-and-infrastructure-fog-i84</guid>
      <description>&lt;p&gt;Enterprise perimeter defenses are fundamentally built on an obsolete assumption that, the developer's workstation is a secure, trusted anchor point. The massive security breach executed by the threat group &lt;strong&gt;TeamPCP&lt;/strong&gt;, resulting in the exfiltration of &lt;strong&gt;3,800 internal GitHub source code repositories&lt;/strong&gt;, completely shattered this illusion.&lt;/p&gt;

&lt;p&gt;This was not a standalone exploit. It was a multi-vector convergence where vulnerabilities in the Node/NPM ecosystem, the systemic ungoverned architecture of the Visual Studio Code Marketplace, and the tactical "fog of war" caused by a period of historic GitHub infrastructure instability came together to create the perfect attack.&lt;/p&gt;

&lt;h2&gt;
  
  
  Phase 1: The Root Exploitation (Node/NPM and the TanStack Supply Chain Pivot)
&lt;/h2&gt;

&lt;p&gt;The kill chain did not begin at GitHub, it originated deep within the modern JavaScript developer tool-chain. TeamPCP executed a localized supply chain compromise targeting upstream open-source utilities, specifically targeting contributors to &lt;strong&gt;TanStack&lt;/strong&gt; npm packages (a widely relied-upon suite for state management and routing).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[TanStack NPM Compromise] 
          │
          ▼
[Stolen 'gh' CLI Tokens] 
          │
          ▼
[Nx Console Pipeline Hijack (No Multi-Admin Approval)]
          │
          ▼
[Malicious Extension Version 18.95.0 Published]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By injecting malicious code into these highly trusted downstream dependencies, the attackers performed targeted local credential harvesting. Their primary target was not production application code, but the development environments of the maintainers themselves.&lt;/p&gt;

&lt;p&gt;The exploit successfully extracted long-lived GitHub CLI (&lt;code&gt;gh&lt;/code&gt;) authentication tokens from a legitimate core developer who maintained both TanStack and the &lt;strong&gt;Nx Console&lt;/strong&gt; ecosystem. Because these developer access tokens lacked granular scoping restrictions, they provided direct administrative write access to the main release pipelines of secondary repositories.&lt;/p&gt;

&lt;h2&gt;
  
  
  Phase 2: VS Code Extension Poisoning (The Nx Console Triage (CVE-2026-48027))
&lt;/h2&gt;

&lt;p&gt;Armed with the stolen &lt;code&gt;gh&lt;/code&gt; tokens, TeamPCP bypassed standard perimeter security by pivoting to the Visual Studio Marketplace. On May 18, version &lt;strong&gt;18.95.0&lt;/strong&gt; of &lt;strong&gt;Nx Console&lt;/strong&gt; (a heavily utilized Monorepo orchestration extension with over 2.2 million installs) was maliciously built and uploaded.&lt;/p&gt;

&lt;p&gt;The deployment revealed two fatal flaws within modern developer workflows,&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The Single-Factor Release Pipeline
&lt;/h3&gt;

&lt;p&gt;The malicious version was uploaded directly to both the Visual Studio Marketplace and the open-source OpenVSX registry. Because the Nx Console publishing architecture lacked a "two-admin manual validation mandate" for automated releases, the publishing pipeline accepted the stolen developer token at face value without triggering a secondary verification gate.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The "Silent Killer": Marketplace Metrics vs. Background Sync
&lt;/h3&gt;

&lt;p&gt;Microsoft’s public marketplace logs initially registered a negligible &lt;strong&gt;28 manual downloads&lt;/strong&gt; before the package was identified and yanked 18 minutes later. However, Nx's internal telemetry revealed that &lt;strong&gt;~6,000 extension activation's&lt;/strong&gt; occurred simultaneously.&lt;/p&gt;

&lt;p&gt;This massive discrepancy highlights the danger of &lt;strong&gt;VS Code's background auto-update synchronization&lt;/strong&gt;. Thousands of developer environments pulled down, unzipped, and executed the malicious version automatically while the developers' IDEs were running in the background.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Example&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;target&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;parameters&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;within&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;compromised&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;developer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;workspaces&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"extensions.autoUpdate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;The&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;default&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;vulnerability&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;exploited&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;by&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;TeamPCP&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"terminal.integrated.profiles.osx"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"malicious-hook"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/bin/bash"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"python3 ~/.local/share/kitty/cat.py &amp;amp;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Node Execution Layer
&lt;/h3&gt;

&lt;p&gt;Upon extension activation, the poisoned payload immediately dropped an obfuscated Node.js post-install hook. Operating completely within user space to evade basic Endpoint Detection and Response (EDR) behavioral hooks, it set an environmental marker (&lt;code&gt;__DAEMONIZED=1&lt;/code&gt;) and spawned a background Python process (&lt;code&gt;cat.py&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;The malware systemically scanned local paths for,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure Configuration:&lt;/strong&gt; Plaintext HashiCorp Vault tokens (&lt;code&gt;~/.vault-token&lt;/code&gt;), local Kubernetes &lt;code&gt;kubeconfig&lt;/code&gt; files, and AWS/Azure IAM metadata endpoint hashes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ecosystem Identity:&lt;/strong&gt; Plaintext &lt;code&gt;.npmrc&lt;/code&gt; registry tokens and active GitHub tokens (&lt;code&gt;ghp_&lt;/code&gt;, &lt;code&gt;gho_&lt;/code&gt;, &lt;code&gt;ghs_&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Active Memory Subsystems:&lt;/strong&gt; Contents of 1Password vaults via the &lt;code&gt;op&lt;/code&gt; CLI by hijacking active, unlocked terminal sessions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Phase 3: The Climax (The Internal GitHub Breach)
&lt;/h2&gt;

&lt;p&gt;The payload achieved its ultimate goal when an internal GitHub software engineer, who utilized Nx Console for local workflow management, had their workstation pull down the background update.&lt;/p&gt;

&lt;p&gt;The malware executed on the engineer's local machine, scraped their active internal enterprise session tokens, and exfiltrated them to a remote command-and-control (C2) server. TeamPCP then used these highly privileged internal access credentials to bypass GitHub's corporate identity perimeters entirely.&lt;/p&gt;

&lt;p&gt;Because internal repository boundaries operate on flat network access structures once an authenticated developer endpoint is cleared, the threat actors systematically cloned and exfiltrated &lt;strong&gt;3,800 proprietary internal GitHub source code repositories&lt;/strong&gt; before the endpoint could be isolated.&lt;/p&gt;

&lt;h2&gt;
  
  
  Phase 4: The Tactical Fog of War (GitHub's Infrastructure Instability)
&lt;/h2&gt;

&lt;p&gt;The velocity and stealth of this attack were significantly aided by an ongoing reliability crisis within GitHub’s core infrastructure. During the 12-month window surrounding the breach, GitHub recorded a massive spike in service degradation.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Total Tracked Incidents:&lt;/strong&gt; 257 distinct technical incidents.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Major Outages:&lt;/strong&gt; 48 major service shutdowns, totaling &lt;strong&gt;112 hours and 18 minutes&lt;/strong&gt; of total downtime.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Primary Failure Vector:&lt;/strong&gt; GitHub Actions experienced 57 outages—three times the incidence rate of core Git storage operations.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Outage Date&lt;/th&gt;
&lt;th&gt;Primary Root Cause&lt;/th&gt;
&lt;th&gt;Security Alert Fallout&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;October 29&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Outage in compute dependency (Microsoft Azure), 90% error rate across Codespaces/ Actions.&lt;/td&gt;
&lt;td&gt;Telemetry gaps, security monitoring systems failed to track cross-border API token replication.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;February 2&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Configuration failure in user settings caching, cascading failures in the Git HTTPS proxy.&lt;/td&gt;
&lt;td&gt;High volume of synchronous cache writes generated a deluge of network errors, masking anomalous Git clone calls.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;February 12&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Authorization claim changes in core networking dependencies,, 90% Codespace provisioning failure.&lt;/td&gt;
&lt;td&gt;Security alerts failed to populate due to misclassified severity ratings, delaying incident detection by hours.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  The Alert Fatigue Vulnerability
&lt;/h3&gt;

&lt;p&gt;This constant infrastructural noise created an ideal tactical environment for the attackers. SecOps and DevSecOps teams were caught in a continuous state of &lt;strong&gt;alert fatigue&lt;/strong&gt; dealing with broken GitHub Actions pipelines, Elasticsearch cluster degradation, and database timeouts.&lt;/p&gt;

&lt;p&gt;When TeamPCP’s automated scripts began running rapid API queries and pulling massive volumes of repository data using the compromised engineer's token, the unusual spikes in data transfer blended into the background noise of an infrastructure already struggling with systemic capacity and networking failures.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hard Takeaways: How Developers Must Harden Their Environments
&lt;/h2&gt;

&lt;p&gt;If your environment was active or using automated tools during this period, you must shift your development machine from an implied trust zone to a completely zero-trust environment.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Kill IDE Auto-Updates Globally
&lt;/h3&gt;

&lt;p&gt;Never allow your IDE to pull un-vetted code in the background. Explicitly configure your editor to require manual permission before updating any third-party extension.&lt;/p&gt;

&lt;p&gt;In VS Code's global &lt;code&gt;settings.json&lt;/code&gt;, enforce:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"extensions.autoUpdate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"extensions.autoCheckUpdates"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Isolate Development Runtimes
&lt;/h3&gt;

&lt;p&gt;Stop running compilers, package managers, and complex IDE extensions directly on your bare-metal operating system.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Utilize isolated, ephemeral development environments (e.g., containerized &lt;strong&gt;Dev containers&lt;/strong&gt; or heavily scoped virtual environments) where local file-system access is completely decoupled from your master &lt;code&gt;~/.ssh/&lt;/code&gt;, &lt;code&gt;~/.aws/&lt;/code&gt;, or &lt;code&gt;.npmrc&lt;/code&gt; configuration folders.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Implement Strict Token Volatility
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Eliminate long-lived personal access tokens (&lt;code&gt;ghp_&lt;/code&gt;). Switch entirely to fine-grained personal access tokens configured with strict, single-repository scope constraints and maximum 7-day expiration dates.&lt;/li&gt;
&lt;li&gt;Explicitly configure your local password managers and authentication tools to require biological verification (e.g., TouchID/FaceID) or short timeout windows for &lt;em&gt;every&lt;/em&gt; individual call executed via the terminal command line (&lt;code&gt;op signin --timeout&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>vulnerabilities</category>
      <category>github</category>
      <category>vscode</category>
      <category>npm</category>
    </item>
    <item>
      <title>Moving Beyond MediatR: Implementing Cross-Cutting Concerns with Native .NET Dependency Injection</title>
      <dc:creator>Akash Lomas</dc:creator>
      <pubDate>Fri, 22 May 2026 03:45:18 +0000</pubDate>
      <link>https://dev.to/akash_lomas_ns/moving-beyond-mediatr-implementing-cross-cutting-concerns-with-native-net-dependency-injection-4ej5</link>
      <guid>https://dev.to/akash_lomas_ns/moving-beyond-mediatr-implementing-cross-cutting-concerns-with-native-net-dependency-injection-4ej5</guid>
      <description>&lt;p&gt;For years, the MediatR package has been a default inclusion in almost every new .NET project template. It is frequently hailed as the gold standard for decoupling controllers or minimal APIs from business logic and implementing Clean Architecture or CQRS patterns.&lt;/p&gt;

&lt;p&gt;However, as ASP.NET Core has matured, many of the architectural justifications for adding MediatR as a heavy third-party dependency have faded. If you are building standard CRUD or even moderately complex enterprise APIs, it might be time to ask yourself,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why am I routing my HTTP requests through an abstract in-memory bus when native alternatives exist?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let’s explore why MediatR might be an unnecessary abstraction in your codebase and how you can replace its most beloved feature Pipeline Behaviors using pure .NET Dependency Injection (DI) plumbing and the Decorator pattern.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Core Critique of MediatR
&lt;/h3&gt;

&lt;p&gt;While MediatR provides an elegant mechanism for decoupling, it introduces specific friction points into a code-base,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Obfuscated Control Flow: Because handlers are resolved dynamically, it is impossible to use standard “Go to Definition” (F12) in your IDE to trace execution directly from an endpoint to its handler. You are forced to search for the corresponding IRequestHandler type implementation.&lt;/li&gt;
&lt;li&gt;Debugging Overhead: Stepping through code becomes a tedious exercise of bypassing internal library code generator stacks instead of moving sequentially through your business logic.&lt;/li&gt;
&lt;li&gt;Unnecessary Architecture: In standard Web APIs, the mapping between an endpoint and its handler is almost always 1:1. Introducing a mediator pattern for a direct request-response cycle over complicates the system with minimal structural payback.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are using Minimal APIs or standard Controllers, you already have powerful endpoint routing. So why use MediatR? The answer almost always boils down to one critical feature, Pipeline Behaviors.&lt;/p&gt;

&lt;h3&gt;
  
  
  The “Killer Feature”: Cross-Cutting Concerns
&lt;/h3&gt;

&lt;p&gt;Developers love MediatR because it makes addressing cross-cutting concerns, such as centralized logging, validation pipelines (e.g., using FluentValidation), metrics collection, and OpenTelemetry tracking incredibly clean.&lt;/p&gt;

&lt;p&gt;Instead of cluttering every single business handler with repetitive try-catch blocks or explicit validation calls, MediatR lets you define a generic middleware pipeline around your requests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// The classic MediatR approach&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddMediatR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RegisterServicesFromAssembly&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Program&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;Assembly&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddOpenBehavior&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LoggingBehavior&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;,&amp;gt;));&lt;/span&gt;
    &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddOpenBehavior&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ValidationBehavior&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;,&amp;gt;));&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is a fantastic architectural model, but you do not need a third-party package to achieve it. Modern .NET allows you to implement this exact pattern natively using compile-time type-safe decorators.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Native Alternative: DI-Based Decoration
&lt;/h3&gt;

&lt;p&gt;Instead of an abstract pipeline behavior model, we can leverage the Decorator Pattern natively supported by the Microsoft.Extensions.DependencyInjection container. This allows us to transparently wrap any standard interface registration with cross-cutting behaviors.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Defining a Domain-Driven Request Handler Interface&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;First, let’s establish our own lightweight, explicit handler contract. This preserves your CQRS separation without binding your domain to external packages.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IRequestHandler&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;TRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TResponse&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TResponse&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;HandleAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TRequest&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CancellationToken&lt;/span&gt; &lt;span class="n"&gt;cancellationToken&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Creating a Concrete Business Handler&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your concrete query or command handlers remain pristine. They are entirely unaware of logging, telemetry, or validation logic, adhering perfectly to the Single Responsibility Principle.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;record&lt;/span&gt; &lt;span class="nc"&gt;CreateProductCommand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;Price&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IRequest&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CreateProductHandler&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IRequestHandler&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;CreateProductCommand&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Guid&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IProductRepository&lt;/span&gt; &lt;span class="n"&gt;_repository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;CreateProductHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IProductRepository&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_repository&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Guid&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;HandleAsync&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="n"&gt;CreateProductCommand&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
         &lt;span class="n"&gt;CancellationToken&lt;/span&gt; &lt;span class="n"&gt;cancellationToken&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Guid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;NewGuid&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="c1"&gt;// Core business logic goes here...&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Implementing the Cross-Cutting Decorator&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, let’s implement a generic decorator that intercepts the request execution. It implements the same interface but accepts the inner concrete handler as a dependency, wrapping it with infrastructure logic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LoggingHandlerDecorator&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TResponse&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IRequestHandler&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TResponse&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IRequestHandler&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TResponse&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_inner&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;ILogger&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;LoggingHandlerDecorator&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TResponse&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;LoggingHandlerDecorator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;IRequestHandler&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TResponse&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="n"&gt;ILogger&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;LoggingHandlerDecorator&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TResponse&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_inner&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;inner&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;_logger&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TResponse&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;HandleAsync&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TRequest&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CancellationToken&lt;/span&gt; &lt;span class="n"&gt;cancellationToken&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;requestName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TRequest&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Executing request: {RequestName}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;requestName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;try&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_inner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;HandleAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cancellationToken&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Successfully executed request: {RequestName}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;requestName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Request failed: {RequestName}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;requestName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Wiring It Together Natively in Program.cs
&lt;/h3&gt;

&lt;p&gt;To register these decorators without external help, we can write a clean extension method using the native DI container’s service factory capabilities. This gives us full architectural control over which handlers get decorated and in what order.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RequestHandlerRegistrationExtensions&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;IServiceCollection&lt;/span&gt; &lt;span class="n"&gt;AddDecoratedRequestHandler&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TResponse&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;THandler&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;IServiceCollection&lt;/span&gt; &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
        &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;THandler&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;IRequestHandler&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TResponse&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// 1. Register the concrete handler with its own concrete type&lt;/span&gt;
        &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddTransient&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;THandler&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// 2. Register the interface using a factory method that constructs the decorator chain&lt;/span&gt;
        &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddTransient&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IRequestHandler&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TResponse&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;sp&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;concreteHandler&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetRequiredService&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;THandler&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetRequiredService&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ILogger&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;LoggingHandlerDecorator&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TResponse&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&amp;gt;();&lt;/span&gt;

            &lt;span class="c1"&gt;// Wrap the core handler with our logging decorator&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;LoggingHandlerDecorator&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TResponse&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;concreteHandler&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Pro-Tip: If manual registration feels too verbose for thousands of handlers, you can use assembly scanning utilities like Scrutor to dynamically apply the .Decorate() method across your entire service collection automatically.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Your application endpoints remain perfectly clean, directly consuming the generic interface via native dependency injection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;MapPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/products"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;CreateProductCommand&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;IRequestHandler&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;CreateProductCommand&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Guid&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;HandleAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Architectural Advantages
&lt;/h3&gt;

&lt;p&gt;By shifting from an in-memory mediator library to native DI decoration, you unlock major engineering benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No Black Boxes: Your execution pathway is clear. If you place a breakpoint inside your API endpoint and step into handler.HandleAsync(), you will sequentially enter the LoggingDecorator, step through any validation layers, and land cleanly inside your actual business logic handler.&lt;/li&gt;
&lt;li&gt;Zero Third-Party Vendor Lock-in: Your core business logic blocks do not depend on external packages. Upgrading your framework version will never be delayed due to a breaking change in an open-source messaging mediator.&lt;/li&gt;
&lt;li&gt;Granular Structural Control: Unlike globally forced middleware pipelines, you can explicitly choose which command or query handlers receive specific decorators. If a high-throughput endpoint requires raw performance without validation overhead, you can register it without its decorator wrap.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;MediatR has served the .NET community exceptionally well over the last decade. However, frameworks evolve. With modern ASP.NET Core DI plumbing, we can maintain clean separation of concerns, enforce CQRS principles, and leverage pipeline behaviors seamlessly using standard patterns built straight into the runtime.&lt;/p&gt;

&lt;p&gt;Evaluate your current architecture.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Is MediatR solving a foundational problem for you, or is it merely acting as boilerplate code that your native framework can already handle?&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>mediatr</category>
      <category>microservices</category>
      <category>dotnet</category>
      <category>cqrs</category>
    </item>
  </channel>
</rss>
