<?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: Arijeet Ganguli</title>
    <description>The latest articles on DEV Community by Arijeet Ganguli (@arijeetganguli).</description>
    <link>https://dev.to/arijeetganguli</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F411952%2Fff61245f-8208-4386-a72c-bee58b6fcb77.png</url>
      <title>DEV Community: Arijeet Ganguli</title>
      <link>https://dev.to/arijeetganguli</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/arijeetganguli"/>
    <language>en</language>
    <item>
      <title>Building Agentra, An Enterprise AI Engineering Control Plane for Secure Coding Agents</title>
      <dc:creator>Arijeet Ganguli</dc:creator>
      <pubDate>Fri, 22 May 2026 18:29:40 +0000</pubDate>
      <link>https://dev.to/arijeetganguli/building-agentra-an-enterprise-ai-engineering-control-plane-for-secure-coding-agents-4ke3</link>
      <guid>https://dev.to/arijeetganguli/building-agentra-an-enterprise-ai-engineering-control-plane-for-secure-coding-agents-4ke3</guid>
      <description>&lt;p&gt;Open source repository:&lt;br&gt;
&lt;a href="https://github.com/arijeetganguli/agentra" rel="noopener noreferrer"&gt;https://github.com/arijeetganguli/agentra&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;PyPI:&lt;br&gt;
&lt;a href="https://pypi.org/project/agentra/" rel="noopener noreferrer"&gt;https://pypi.org/project/agentra/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;AI coding agents are becoming part of everyday engineering workflows.&lt;/p&gt;

&lt;p&gt;Cursor, Claude, Copilot, Aider, Windsurf, and autonomous coding systems are now generating infrastructure code, migrations, CI pipelines, shell scripts, and production changes.&lt;/p&gt;

&lt;p&gt;That changes the engineering risk model completely.&lt;/p&gt;

&lt;p&gt;Most teams are currently relying on:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;ad hoc prompt rules&lt;/li&gt;
&lt;li&gt;README instructions&lt;/li&gt;
&lt;li&gt;tribal knowledge&lt;/li&gt;
&lt;li&gt;manual reviews&lt;/li&gt;
&lt;li&gt;loosely enforced conventions&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That approach breaks down quickly at scale.&lt;/p&gt;

&lt;p&gt;AI agents can:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;execute unsafe shell commands&lt;/li&gt;
&lt;li&gt;generate destructive SQL&lt;/li&gt;
&lt;li&gt;leak secrets&lt;/li&gt;
&lt;li&gt;create insecure infrastructure&lt;/li&gt;
&lt;li&gt;waste huge amounts of tokens&lt;/li&gt;
&lt;li&gt;follow prompt injections hidden in repositories&lt;/li&gt;
&lt;li&gt;create inconsistent workflows across teams&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I started building Agentra to solve this problem.&lt;/p&gt;

&lt;p&gt;Agentra is an enterprise AI engineering control plane for coding agents.&lt;/p&gt;

&lt;p&gt;The idea is simple:&lt;/p&gt;

&lt;p&gt;Treat AI coding workflows with the same rigor as infrastructure and DevSecOps systems.&lt;/p&gt;
&lt;h2&gt;
  
  
  What Agentra Does
&lt;/h2&gt;

&lt;p&gt;Agentra sits between developers and coding agents.&lt;/p&gt;

&lt;p&gt;It provides:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;stack aware governance&lt;/li&gt;
&lt;li&gt;runtime safety controls&lt;/li&gt;
&lt;li&gt;token optimization&lt;/li&gt;
&lt;li&gt;prompt injection defense&lt;/li&gt;
&lt;li&gt;secure execution policies&lt;/li&gt;
&lt;li&gt;context minimization&lt;/li&gt;
&lt;li&gt;intelligent onboarding&lt;/li&gt;
&lt;li&gt;enterprise policy enforcement&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Instead of static prompt templates, Agentra dynamically builds optimized instructions based on the detected project stack.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ag init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agentra detects:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;frameworks&lt;/li&gt;
&lt;li&gt;SDKs&lt;/li&gt;
&lt;li&gt;infrastructure tooling&lt;/li&gt;
&lt;li&gt;databases&lt;/li&gt;
&lt;li&gt;cloud providers&lt;/li&gt;
&lt;li&gt;agent platforms&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Then it generates optimized governance instructions for:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Claude&lt;/li&gt;
&lt;li&gt;Cursor&lt;/li&gt;
&lt;li&gt;Copilot&lt;/li&gt;
&lt;li&gt;Aider&lt;/li&gt;
&lt;li&gt;Windsurf&lt;/li&gt;
&lt;li&gt;AGENTS.md&lt;/li&gt;
&lt;li&gt;CLAUDE.md&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Why Existing Approaches Are Not Enough
&lt;/h2&gt;

&lt;p&gt;Most prompt engineering workflows are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;static&lt;/li&gt;
&lt;li&gt;duplicated&lt;/li&gt;
&lt;li&gt;token inefficient&lt;/li&gt;
&lt;li&gt;difficult to maintain&lt;/li&gt;
&lt;li&gt;easy to bypass&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Security enforcement is usually disconnected from the actual runtime.&lt;/p&gt;

&lt;p&gt;Agentra tries to close that gap.&lt;/p&gt;

&lt;h2&gt;
  
  
  Core Security Philosophy
&lt;/h2&gt;

&lt;p&gt;Agentra follows several strict principles.&lt;/p&gt;

&lt;h2&gt;
  
  
  No Destructive Operations By Default
&lt;/h2&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;never execute DROP/TRUNCATE automatically&lt;/li&gt;
&lt;li&gt;require approvals for destructive actions&lt;/li&gt;
&lt;li&gt;generate rollback plans&lt;/li&gt;
&lt;li&gt;prevent production mutations without confirmation&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  EDR Safe Execution
&lt;/h2&gt;

&lt;p&gt;Inline shell execution often triggers enterprise security systems.&lt;/p&gt;

&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"..."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agentra prefers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;create temp file → validate → execute
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This reduces security tooling alerts from systems like CrowdStrike.&lt;/p&gt;

&lt;h2&gt;
  
  
  Secret Safety
&lt;/h2&gt;

&lt;p&gt;Agentra blocks:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;hardcoded credentials&lt;/li&gt;
&lt;li&gt;secret logging&lt;/li&gt;
&lt;li&gt;unsafe token persistence&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It prefers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;.env files&lt;/li&gt;
&lt;li&gt;secret managers&lt;/li&gt;
&lt;li&gt;runtime injection&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Prompt Injection Defense
&lt;/h2&gt;

&lt;p&gt;Repositories increasingly contain hidden prompt attacks.&lt;/p&gt;

&lt;p&gt;Agentra treats repository instructions as untrusted by default.&lt;/p&gt;

&lt;h2&gt;
  
  
  Token Optimization Matters
&lt;/h2&gt;

&lt;p&gt;One thing I realized quickly:&lt;/p&gt;

&lt;p&gt;Most AI engineering systems waste huge amounts of tokens.&lt;/p&gt;

&lt;p&gt;Teams repeatedly inject:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;duplicate instructions&lt;/li&gt;
&lt;li&gt;irrelevant docs&lt;/li&gt;
&lt;li&gt;giant READMEs&lt;/li&gt;
&lt;li&gt;unnecessary context&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Agentra aggressively minimizes context.&lt;/p&gt;

&lt;p&gt;It uses:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;instruction deduplication&lt;/li&gt;
&lt;li&gt;semantic summarization&lt;/li&gt;
&lt;li&gt;relevance filtering&lt;/li&gt;
&lt;li&gt;context TTL&lt;/li&gt;
&lt;li&gt;dynamic instruction composition&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The goal is:&lt;/p&gt;

&lt;p&gt;Better outputs at lower cost.&lt;/p&gt;

&lt;h2&gt;
  
  
  Local First Architecture
&lt;/h2&gt;

&lt;p&gt;Another important design decision:&lt;/p&gt;

&lt;p&gt;Agentra is local first.&lt;/p&gt;

&lt;p&gt;No hidden telemetry.&lt;br&gt;
No forced cloud dependency.&lt;br&gt;
No black box execution.&lt;/p&gt;

&lt;p&gt;Enterprise engineering teams increasingly care about:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;governance&lt;/li&gt;
&lt;li&gt;auditability&lt;/li&gt;
&lt;li&gt;reproducibility&lt;/li&gt;
&lt;li&gt;deterministic execution&lt;/li&gt;
&lt;li&gt;data control&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Local first architecture aligns with those requirements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Karpathy Inspired Engineering Principles
&lt;/h2&gt;

&lt;p&gt;I also wanted the platform to encourage simpler engineering.&lt;/p&gt;

&lt;p&gt;Many AI generated codebases become:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;over abstracted&lt;/li&gt;
&lt;li&gt;dependency heavy&lt;/li&gt;
&lt;li&gt;difficult to debug&lt;/li&gt;
&lt;li&gt;operationally fragile&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Agentra includes engineering skills inspired by Andrej Karpathy style principles:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;simple over clever&lt;/li&gt;
&lt;li&gt;readable code first&lt;/li&gt;
&lt;li&gt;deterministic workflows&lt;/li&gt;
&lt;li&gt;small composable modules&lt;/li&gt;
&lt;li&gt;transparent execution&lt;/li&gt;
&lt;li&gt;local reproducibility&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Enterprise Direction
&lt;/h2&gt;

&lt;p&gt;The long term vision is larger than prompt templates.&lt;/p&gt;

&lt;p&gt;Agentra is evolving into:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;AI engineering governance&lt;/li&gt;
&lt;li&gt;runtime policy enforcement&lt;/li&gt;
&lt;li&gt;context orchestration&lt;/li&gt;
&lt;li&gt;secure execution infrastructure&lt;/li&gt;
&lt;li&gt;multi agent governance&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Think:&lt;/p&gt;

&lt;p&gt;“DevSecOps for coding agents.”&lt;/p&gt;

&lt;h2&gt;
  
  
  Current Focus
&lt;/h2&gt;

&lt;p&gt;The initial version focuses on:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;stack detection&lt;/li&gt;
&lt;li&gt;secure AGENTS.md generation&lt;/li&gt;
&lt;li&gt;token optimization&lt;/li&gt;
&lt;li&gt;runtime guardrails&lt;/li&gt;
&lt;li&gt;enterprise security defaults&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The goal is to keep the first release focused and operationally useful.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;AI coding systems are becoming part of the software delivery lifecycle.&lt;/p&gt;

&lt;p&gt;That means:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;governance matters&lt;/li&gt;
&lt;li&gt;runtime safety matters&lt;/li&gt;
&lt;li&gt;context quality matters&lt;/li&gt;
&lt;li&gt;token efficiency matters&lt;/li&gt;
&lt;li&gt;deterministic execution matters&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The industry needs more than prompt templates.&lt;/p&gt;

&lt;p&gt;It needs engineering control planes.&lt;/p&gt;

&lt;p&gt;That is the direction behind Agentra.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Agentra is available as an open source Python package.&lt;/p&gt;

&lt;h3&gt;
  
  
  Install
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;agentra
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Initialize In Your Project
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ag init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agentra will:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;detect your stack&lt;/li&gt;
&lt;li&gt;identify frameworks and SDKs&lt;/li&gt;
&lt;li&gt;generate optimized agent instructions&lt;/li&gt;
&lt;li&gt;apply enterprise security defaults&lt;/li&gt;
&lt;li&gt;create governance aware configuration&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  GitHub Repository
&lt;/h3&gt;

&lt;p&gt;GitHub:&lt;br&gt;
&lt;a href="https://github.com/arijeetganguli/agentra" rel="noopener noreferrer"&gt;https://github.com/arijeetganguli/agentra&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The repository includes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;CLI tooling&lt;/li&gt;
&lt;li&gt;stack detection&lt;/li&gt;
&lt;li&gt;policy engine&lt;/li&gt;
&lt;li&gt;token optimization&lt;/li&gt;
&lt;li&gt;secure execution guardrails&lt;/li&gt;
&lt;li&gt;AGENTS.md generation&lt;/li&gt;
&lt;li&gt;enterprise governance workflows&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Contributions, feedback, and security discussions are welcome.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>devsecops</category>
      <category>security</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Building the Fastest .NET Object Mapper</title>
      <dc:creator>Arijeet Ganguli</dc:creator>
      <pubDate>Tue, 31 Mar 2026 05:32:14 +0000</pubDate>
      <link>https://dev.to/arijeetganguli/building-the-fastest-net-object-mapper-288g</link>
      <guid>https://dev.to/arijeetganguli/building-the-fastest-net-object-mapper-288g</guid>
      <description>&lt;p&gt;&lt;strong&gt;How compiled expression trees and cycle analysis beat Mapster, AutoMapper, and hand-tuned reflection.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;Every .NET project eventually needs object mapping. &lt;code&gt;User&lt;/code&gt; → &lt;code&gt;UserDto&lt;/code&gt;. &lt;code&gt;Order&lt;/code&gt; → &lt;code&gt;OrderResponse&lt;/code&gt;. You've done it a thousand times. And you've probably reached for AutoMapper or Mapster — because why write &lt;code&gt;dest.Name = src.Name&lt;/code&gt; fifty times?&lt;/p&gt;

&lt;p&gt;But there's a problem nobody talks about.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Friday Incident
&lt;/h2&gt;

&lt;p&gt;A developer on our team added a &lt;code&gt;Parent&lt;/code&gt; property to a &lt;code&gt;Node&lt;/code&gt; class. Standard tree structure. The mapper tried to map &lt;code&gt;Node.Parent.Parent.Parent...&lt;/code&gt; until the stack overflowed. Production went down. No exception was caught — &lt;code&gt;StackOverflowException&lt;/code&gt; is uncatchable in .NET.&lt;/p&gt;

&lt;p&gt;We looked at every major mapping library. &lt;strong&gt;None of them had cycle detection.&lt;/strong&gt; Not AutoMapper. Not Mapster. Not PanoramicData.Mapper.&lt;/p&gt;

&lt;p&gt;So we built one that does.&lt;/p&gt;

&lt;h2&gt;
  
  
  But We Didn't Want to Be the Slowest
&lt;/h2&gt;

&lt;p&gt;The first version used reflection. It was safe — cycle detection worked, max-depth enforcement worked, configuration validation caught missing mappings at startup. But it was slow. Really slow.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Mean&lt;/th&gt;
&lt;th&gt;vs Manual&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Manual Mapping&lt;/td&gt;
&lt;td&gt;~17 ns&lt;/td&gt;
&lt;td&gt;baseline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mapster&lt;/td&gt;
&lt;td&gt;~23 ns&lt;/td&gt;
&lt;td&gt;1.4x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AutoMapper&lt;/td&gt;
&lt;td&gt;~63 ns&lt;/td&gt;
&lt;td&gt;3.7x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mapture v0 (refl.)&lt;/td&gt;
&lt;td&gt;~773 ns&lt;/td&gt;
&lt;td&gt;45x&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;45x slower than hand-written code. That's not a rounding error.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Rewrite: Compiled Expression Trees
&lt;/h2&gt;

&lt;p&gt;The insight: &lt;strong&gt;reflection is only slow when you do it on every call.&lt;/strong&gt; What if you did reflection &lt;em&gt;once&lt;/em&gt; — at configuration time — and compiled the result into a native delegate?&lt;/p&gt;

&lt;p&gt;That's exactly what &lt;code&gt;System.Linq.Expressions&lt;/code&gt; lets you do:&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;// At configuration time, Mapture builds this:&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;param&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Expression&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Parameter&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;User&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;body&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Expression&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;MemberInit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;Expression&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;New&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;UserDto&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="n"&gt;Expression&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;destNameProp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Expression&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Property&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;srcNameProp&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="n"&gt;Expression&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;destAgeProp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Expression&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Property&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;srcAgeProp&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;lambda&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Expression&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Lambda&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Func&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;UserDto&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Func&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;UserDto&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;compiled&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lambda&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Compile&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// On every Map() call, Mapture just does:&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;compiled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The compiled delegate is essentially the same IL that the JIT would produce for hand-written &lt;code&gt;new UserDto { Name = src.Name, Age = src.Age }&lt;/code&gt;. No reflection. No dictionary lookups. No allocations beyond the destination object.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Trick: Separate Fast and Slow Paths
&lt;/h2&gt;

&lt;p&gt;Here's the key optimization most mappers miss. &lt;strong&gt;Most types don't have cycles.&lt;/strong&gt; &lt;code&gt;User&lt;/code&gt; → &lt;code&gt;UserDto&lt;/code&gt; will never cause infinite recursion. Only self-referencing types like &lt;code&gt;Node&lt;/code&gt; → &lt;code&gt;NodeDto&lt;/code&gt; (where &lt;code&gt;Node&lt;/code&gt; has a &lt;code&gt;Node Parent&lt;/code&gt; property) can cycle.&lt;/p&gt;

&lt;p&gt;So at configuration time, Mapture runs a graph traversal on your type maps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User → UserDto          → acyclic (fast path)
Order → OrderDto        → acyclic (fast path)  
Node → NodeDto          → CYCLIC (needs tracking)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Acyclic types get a pure delegate — no &lt;code&gt;HashSet&amp;lt;object&amp;gt;&lt;/code&gt;, no depth counter, zero overhead. Cyclic types get wrapped with a visited set and a depth counter. You get safety where you need it and raw speed everywhere else.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three More Tricks
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Embedded nested delegates.&lt;/strong&gt; When &lt;code&gt;Order&lt;/code&gt; has an &lt;code&gt;Address&lt;/code&gt; property, the compiled delegate for &lt;code&gt;Address → AddressDto&lt;/code&gt; is embedded directly into the &lt;code&gt;Order → OrderDto&lt;/code&gt; expression tree as a constant. No type-pair lookup per nested object.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Typed delegates.&lt;/strong&gt; Instead of &lt;code&gt;Func&amp;lt;object, object&amp;gt;&lt;/code&gt; (which boxes value types), Mapture caches &lt;code&gt;Func&amp;lt;TSource, TDestination&amp;gt;&lt;/code&gt; per generic type pair. Zero boxing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Thread-static cache.&lt;/strong&gt; The hot path doesn't even hit a &lt;code&gt;ConcurrentDictionary&lt;/code&gt;. It reads from a &lt;code&gt;[ThreadStatic]&lt;/code&gt; slot in a static generic class &lt;code&gt;TypePairCache&amp;lt;TSource, TDestination&amp;gt;&lt;/code&gt;. That's a single field read — essentially free.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Result
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Rank&lt;/th&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Mean&lt;/th&gt;
&lt;th&gt;vs Manual&lt;/th&gt;
&lt;th&gt;Allocated&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;🥇&lt;/td&gt;
&lt;td&gt;Manual Mapping&lt;/td&gt;
&lt;td&gt;~17 ns&lt;/td&gt;
&lt;td&gt;baseline&lt;/td&gt;
&lt;td&gt;96 B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🥈&lt;/td&gt;
&lt;td&gt;Mapture&lt;/td&gt;
&lt;td&gt;~25 ns&lt;/td&gt;
&lt;td&gt;1.5x&lt;/td&gt;
&lt;td&gt;96 B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🥉&lt;/td&gt;
&lt;td&gt;Mapster&lt;/td&gt;
&lt;td&gt;~27 ns&lt;/td&gt;
&lt;td&gt;1.6x&lt;/td&gt;
&lt;td&gt;96 B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;AutoMapper&lt;/td&gt;
&lt;td&gt;~68 ns&lt;/td&gt;
&lt;td&gt;4.0x&lt;/td&gt;
&lt;td&gt;96 B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;PanoramicData.Mapper&lt;/td&gt;
&lt;td&gt;~283 ns&lt;/td&gt;
&lt;td&gt;16.9x&lt;/td&gt;
&lt;td&gt;272 B&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;From 773 ns to 25 ns. From last place to first.&lt;/p&gt;

&lt;p&gt;And it still has cycle detection, max-depth enforcement, and configuration validation — features none of the faster alternatives offer.&lt;/p&gt;

&lt;h2&gt;
  
  
  The ~8 ns Gap
&lt;/h2&gt;

&lt;p&gt;Why not zero overhead? Two things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Delegate invocation&lt;/strong&gt; (~2–3 ns): calling a compiled &lt;code&gt;Func&amp;lt;T,R&amp;gt;&lt;/code&gt; is slightly slower than inlined code&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cache lookup&lt;/strong&gt; (~3–5 ns): reading the thread-static delegate slot&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For context, a single database query takes 500,000–5,000,000 ns. The 8 ns gap is undetectable in any real application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Migration from AutoMapper
&lt;/h2&gt;

&lt;p&gt;Mapture uses the same API patterns. Most migrations are a find-and-replace:&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;// Before&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;AutoMapper&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;AddAutoMapper&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;Startup&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// After&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Mapture&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;AddMapture&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;Startup&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same &lt;code&gt;Profile&lt;/code&gt;, &lt;code&gt;CreateMap&lt;/code&gt;, &lt;code&gt;ForMember&lt;/code&gt;, &lt;code&gt;Ignore&lt;/code&gt;, &lt;code&gt;ReverseMap&lt;/code&gt;. The API was designed so you can migrate in under 30 minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet add package Mapture
dotnet add package Mapture.Extensions.DependencyInjection
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GitHub: &lt;a href="https://github.com/arijeetganguli/Mapture" rel="noopener noreferrer"&gt;github.com/arijeetganguli/Mapture&lt;/a&gt;&lt;br&gt;
NuGet: &lt;a href="https://www.nuget.org/packages/Mapture/" rel="noopener noreferrer"&gt;nuget.org/packages/Mapture&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Targets: .NET Framework 4.8, .NET Standard 2.0, .NET 8, .NET 10.&lt;/p&gt;

&lt;p&gt;MIT licensed. Zero telemetry. 81 tests across 3 frameworks.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Benchmarks measured with BenchmarkDotNet on .NET 10.0, X64 RyuJIT AVX2. Source code and benchmark project included in the repository.&lt;/em&gt;&lt;/p&gt;




</description>
      <category>opensource</category>
      <category>dotnet</category>
      <category>csharp</category>
      <category>performance</category>
    </item>
  </channel>
</rss>
