<?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: Steven Kamwaza</title>
    <description>The latest articles on DEV Community by Steven Kamwaza (@stevenkamwaza).</description>
    <link>https://dev.to/stevenkamwaza</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%2F4044864%2F00e2f32f-7185-4fc7-b652-212acb9d4d25.png</url>
      <title>DEV Community: Steven Kamwaza</title>
      <link>https://dev.to/stevenkamwaza</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/stevenkamwaza"/>
    <language>en</language>
    <item>
      <title>Twinify 1.0.2: A Look at the Latest Performance Improvements</title>
      <dc:creator>Steven Kamwaza</dc:creator>
      <pubDate>Wed, 19 Aug 2026 06:15:59 +0000</pubDate>
      <link>https://dev.to/stevenkamwaza/twinify-102-a-look-at-the-latest-performance-improvements-lap</link>
      <guid>https://dev.to/stevenkamwaza/twinify-102-a-look-at-the-latest-performance-improvements-lap</guid>
      <description>&lt;p&gt;Over the past few weeks, the performance and memory efficiency of &lt;strong&gt;Twinify&lt;/strong&gt; has been improved, twinify is an open-source object-to-object mapping library for .NET.&lt;/p&gt;

&lt;p&gt;The latest release, &lt;strong&gt;Twinify 1.0.2&lt;/strong&gt;, brings some encouraging improvements compared with the initial 1.0.0 release.&lt;/p&gt;

&lt;p&gt;I also wanted to keep the benchmarking honest, so the tests include &lt;strong&gt;AutoMapper 16.2.0&lt;/strong&gt; as a reference point.&lt;/p&gt;

&lt;p&gt;Twinify is designed to make object mapping simple, while supporting common scenarios such as nested objects, collections, flattening, constructor mapping, and custom mappings.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Benchmark
&lt;/h2&gt;

&lt;p&gt;The benchmark uses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;.NET 10&lt;/li&gt;
&lt;li&gt;BenchmarkDotNet 0.15.8&lt;/li&gt;
&lt;li&gt;Windows 11&lt;/li&gt;
&lt;li&gt;Intel Core i7-1355U&lt;/li&gt;
&lt;li&gt;Twinify 1.0.0&lt;/li&gt;
&lt;li&gt;Twinify 1.0.2&lt;/li&gt;
&lt;li&gt;AutoMapper 16.2.0&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The object graph being mapped is not just a simple flat object.&lt;/p&gt;

&lt;p&gt;The benchmark 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
 ├── Address
 └── Orders
      ├── Order
      │    └── OrderItems
      └── Order
           └── OrderItems
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two scenarios are tested:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Mapping a single &lt;code&gt;User&lt;/code&gt; to &lt;code&gt;UserDto&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Mapping 1,000 users to &lt;code&gt;UserDto&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Memory allocation and GC activity are also measured using BenchmarkDotNet's &lt;code&gt;MemoryDiagnoser&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance Progress
&lt;/h2&gt;

&lt;p&gt;Here are the results.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Twinify 1.0.0&lt;/th&gt;
&lt;th&gt;Twinify 1.0.2&lt;/th&gt;
&lt;th&gt;AutoMapper 16.2.0&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Single User&lt;/td&gt;
&lt;td&gt;Mean&lt;/td&gt;
&lt;td&gt;3.819 μs&lt;/td&gt;
&lt;td&gt;4.087 μs&lt;/td&gt;
&lt;td&gt;1.066 μs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Single User&lt;/td&gt;
&lt;td&gt;Allocated&lt;/td&gt;
&lt;td&gt;3,304 B&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1,848 B&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;848 B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1,000 Users&lt;/td&gt;
&lt;td&gt;Mean&lt;/td&gt;
&lt;td&gt;4,420.174 μs&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2,420.444 μs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1,108.267 μs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1,000 Users&lt;/td&gt;
&lt;td&gt;Allocated&lt;/td&gt;
&lt;td&gt;3,320,120 B&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1,864,120 B&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;864,120 B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1,000 Users&lt;/td&gt;
&lt;td&gt;Gen0&lt;/td&gt;
&lt;td&gt;523.4375&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;296.8750&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;136.7188&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1,000 Users&lt;/td&gt;
&lt;td&gt;Gen1&lt;/td&gt;
&lt;td&gt;242.1875&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;171.8750&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;78.1250&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  45% Faster Bulk Mapping
&lt;/h2&gt;

&lt;p&gt;The biggest improvement can be seen when mapping 1,000 users.&lt;/p&gt;

&lt;p&gt;Twinify 1.0.0:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;4,420.174 μs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Twinify 1.0.2:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2,420.444 μs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's approximately a &lt;strong&gt;45% reduction in execution time&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The performance gap with AutoMapper has also become much smaller.&lt;/p&gt;

&lt;p&gt;AutoMapper 16.2.0 completes the same benchmark in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1,108.267 μs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is still a gap, but the improvement from the initial Twinify release is significant.&lt;/p&gt;

&lt;h2&gt;
  
  
  44% Less Memory Allocation
&lt;/h2&gt;

&lt;p&gt;Performance isn't only about execution time.&lt;/p&gt;

&lt;p&gt;For the 1,000-user benchmark:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Twinify 1.0.0
3,320,120 B

Twinify 1.0.2
1,864,120 B
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's approximately &lt;strong&gt;44% less memory allocation&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This is particularly important for applications performing large numbers of mappings because unnecessary allocations can increase GC pressure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reduced GC Pressure
&lt;/h2&gt;

&lt;p&gt;The reduction in allocations is also reflected in the GC measurements.&lt;/p&gt;

&lt;p&gt;For the 1,000-user benchmark, Gen0 collections dropped from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;523.4375 → 296.8750
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's approximately a &lt;strong&gt;43% reduction&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Gen1 also decreased:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;242.1875 → 171.8750
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or approximately &lt;strong&gt;29%&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;These improvements are encouraging because they show that the memory optimizations are not simply reflected in the allocation column; they are also reducing GC activity.&lt;/p&gt;

&lt;h2&gt;
  
  
  What About AutoMapper?
&lt;/h2&gt;

&lt;p&gt;AutoMapper 16.2.0 is still ahead in this benchmark.&lt;/p&gt;

&lt;p&gt;For 1,000 users:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Twinify 1.0.2   2,420.444 μs
AutoMapper      1,108.267 μs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And in allocations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Twinify 1.0.2   1,864,120 B
AutoMapper        864,120 B
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So there is still work to do.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;The next optimization targets are clear.&lt;/p&gt;

&lt;p&gt;I'm particularly interested in reducing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mapping execution overhead&lt;/li&gt;
&lt;li&gt;Allocations during nested and collection mapping&lt;/li&gt;
&lt;li&gt;Reflection or dynamic dispatch on the hot path&lt;/li&gt;
&lt;li&gt;Temporary objects and collections&lt;/li&gt;
&lt;li&gt;GC pressure during large mapping operations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The current results already show that there is plenty of room for optimization.&lt;/p&gt;

&lt;p&gt;The next milestone is to continue closing the gap while keeping Twinify's API simple and predictable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Benchmark?
&lt;/h2&gt;

&lt;p&gt;One of the things I want to emphasize with Twinify is that performance claims should be backed by reproducible benchmarks.&lt;/p&gt;

&lt;p&gt;Rather than simply saying that a mapper is "fast", I'm trying to track actual changes between releases.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Twinify 1.0.0
      ↓
4.42 ms / 1,000 users
      ↓
Twinify 1.0.2
      ↓
2.42 ms / 1,000 users
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That gives future releases something concrete to improve against.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try Twinify
&lt;/h2&gt;

&lt;p&gt;Twinify is available on NuGet and the documentation contains examples covering profiles, nested mappings, collections, dependency injection, and other mapping scenarios.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Documentation:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/StevenKamwaza/Twinify.Docs?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;Twinify Documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NuGet:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://www.nuget.org/packages/Twinify?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;Twinify on NuGet&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The current NuGet listing identifies &lt;strong&gt;1.0.2 as the latest Twinify release&lt;/strong&gt;.&lt;/p&gt;

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

&lt;p&gt;Twinify 1.0.2 is another step forward.&lt;/p&gt;

&lt;p&gt;The current benchmark shows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🚀 &lt;strong&gt;45% faster&lt;/strong&gt; bulk mapping compared with Twinify 1.0.0&lt;/li&gt;
&lt;li&gt;💾 &lt;strong&gt;44% less memory allocation&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;♻️ &lt;strong&gt;43% fewer Gen0 collections&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;📈 A significantly smaller performance gap compared with the initial release&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is still a lot of optimization ahead, and that's part of the fun.&lt;/p&gt;

&lt;p&gt;I'm looking forward to seeing how far Twinify can go.&lt;/p&gt;

&lt;p&gt;If you're interested in .NET object mapping, performance optimization, or open-source development, I'd love to hear your thoughts and feedback.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Twinify — Object Mapping Made Simple.&lt;/strong&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  dotnet #csharp #opensource #performance
&lt;/h1&gt;

</description>
      <category>dotnet</category>
      <category>opensource</category>
      <category>performance</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Getting Started with Twinify: A Free, Open-Source Object Mapper for Modern .NET</title>
      <dc:creator>Steven Kamwaza</dc:creator>
      <pubDate>Fri, 24 Jul 2026 05:44:07 +0000</pubDate>
      <link>https://dev.to/stevenkamwaza/getting-started-with-twinify-a-free-open-source-object-mapper-for-modern-net-2hn3</link>
      <guid>https://dev.to/stevenkamwaza/getting-started-with-twinify-a-free-open-source-object-mapper-for-modern-net-2hn3</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbab5e6yd0ozahjxta014.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbab5e6yd0ozahjxta014.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Lightweight. Familiar. MIT Licensed. Built for .NET 8, 9, and 10.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Following AutoMapper's recent licensing changes, many .NET developers have started looking for an open-source alternative that doesn't require rewriting years of mapping code.&lt;/p&gt;

&lt;p&gt;That's one of the reasons I built &lt;strong&gt;Twinify&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Twinify is a lightweight, high-performance object-to-object mapper that provides a familiar fluent API, making it easy to map DTOs, entities, view models, records, and complex object graphs while remaining completely open source under the &lt;strong&gt;MIT License&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you're already using AutoMapper, you'll find the transition straightforward for many common mapping scenarios.&lt;/p&gt;




&lt;h1&gt;
  
  
  Why Twinify?
&lt;/h1&gt;

&lt;p&gt;✔ MIT Licensed&lt;/p&gt;

&lt;p&gt;✔ Built for .NET 8, .NET 9 &amp;amp; .NET 10&lt;/p&gt;

&lt;p&gt;✔ Familiar AutoMapper-style Fluent API&lt;/p&gt;

&lt;p&gt;✔ Dependency Injection Support&lt;/p&gt;

&lt;p&gt;✔ Automatic Convention-Based Mapping&lt;/p&gt;

&lt;p&gt;✔ Nested Objects &amp;amp; Collections&lt;/p&gt;

&lt;p&gt;✔ Flattening&lt;/p&gt;

&lt;p&gt;✔ Record &amp;amp; Constructor Mapping&lt;/p&gt;

&lt;p&gt;✔ Mapping Diagnostics with &lt;code&gt;Explain&amp;lt;TSource, TDestination&amp;gt;()&lt;/code&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  Installation
&lt;/h1&gt;

&lt;p&gt;Install the required packages.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;






&lt;h1&gt;
  
  
  Step 1 — Create a Mapping Profile
&lt;/h1&gt;

&lt;p&gt;Define your mappings by inheriting from &lt;code&gt;MappingProfile&lt;/code&gt;.&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;UserProfile&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;MappingProfile&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;UserProfile&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;CreateMap&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="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ForMember&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FullName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;opt&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;opt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;MapFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FirstName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LastName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ForMember&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;opt&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;opt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Ignore&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;p&gt;Twinify uses a familiar fluent configuration model that should feel natural to developers coming from AutoMapper.&lt;/p&gt;




&lt;h1&gt;
  
  
  Step 2 — Register Twinify
&lt;/h1&gt;

&lt;p&gt;Register your mapping profiles during application startup.&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;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;AddTwinify&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="n"&gt;AddProfile&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;UserProfile&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Step 3 — Map Your Objects
&lt;/h1&gt;

&lt;p&gt;Inject &lt;code&gt;IMapper&lt;/code&gt; wherever it's needed.&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;UserService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IMapper&lt;/span&gt; &lt;span class="n"&gt;mapper&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="n"&gt;UserDto&lt;/span&gt; &lt;span class="nf"&gt;GetUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="n"&gt;user&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;mapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&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;user&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;p&gt;That's all you need.&lt;/p&gt;

&lt;p&gt;Twinify automatically maps properties with matching names while allowing full customization when required.&lt;/p&gt;




&lt;h1&gt;
  
  
  Features
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Automatic Convention Mapping
&lt;/h2&gt;

&lt;p&gt;Properties with identical names are mapped automatically.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User.Name
        ↓
UserDto.Name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No configuration required.&lt;/p&gt;




&lt;h2&gt;
  
  
  Automatic Flattening
&lt;/h2&gt;

&lt;p&gt;Nested properties are flattened automatically.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Source

User.Address.City

↓

Destination

UserDto.AddressCity
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Nested Object Mapping
&lt;/h2&gt;

&lt;p&gt;Twinify recursively maps nested object graphs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Order
 └── Customer
 └── Address
 └── Contacts

↓

OrderDto
 └── CustomerDto
 └── AddressDto
 └── ContactDtos
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Collection Mapping
&lt;/h2&gt;

&lt;p&gt;Supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lists&lt;/li&gt;
&lt;li&gt;Arrays&lt;/li&gt;
&lt;li&gt;Dictionaries&lt;/li&gt;
&lt;li&gt;Nested collections&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Constructor &amp;amp; Record Mapping
&lt;/h2&gt;

&lt;p&gt;Twinify automatically constructs destination types, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Immutable objects&lt;/li&gt;
&lt;li&gt;Records&lt;/li&gt;
&lt;li&gt;Parameterized constructors&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Fluent Configuration
&lt;/h2&gt;

&lt;p&gt;Twinify supports a rich configuration API, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;CreateMap&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ForMember&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MapFrom&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Ignore&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Condition&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ConvertUsing&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;BeforeMap&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AfterMap&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ReverseMap&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;IncludeBase&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PreserveReferences&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Explain Your Mappings
&lt;/h2&gt;

&lt;p&gt;One feature that sets Twinify apart is mapping diagnostics.&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;mapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Explain&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of guessing why a property mapped the way it did, &lt;code&gt;Explain()&lt;/code&gt; shows exactly where every destination member receives its value, making debugging significantly easier.&lt;/p&gt;




&lt;h1&gt;
  
  
  Migrating from AutoMapper
&lt;/h1&gt;

&lt;p&gt;Many existing AutoMapper projects can migrate with only a few mechanical changes.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;AutoMapper&lt;/th&gt;
&lt;th&gt;Twinify&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Profile&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MappingProfile&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CreateMap()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Same familiar API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ForMember()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Same familiar API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;MapFrom()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Same familiar API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ReverseMap()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;AddAutoMapper()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;AddTwinify()&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Custom resolvers&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;ConvertUsing()&lt;/code&gt; and member configuration&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Migration Guide
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Remove AutoMapper
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet remove package AutoMapper
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  2. Install Twinify
&lt;/h3&gt;



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

&lt;/div&gt;






&lt;h3&gt;
  
  
  3. Update Your Profiles
&lt;/h3&gt;

&lt;p&gt;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="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserProfile&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Profile&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with&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;UserProfile&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;MappingProfile&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  4. Update Dependency Injection
&lt;/h3&gt;

&lt;p&gt;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="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;AddAutoMapper&lt;/span&gt;&lt;span class="p"&gt;(...);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with&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;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;AddTwinify&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="n"&gt;AddProfile&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;UserProfile&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  5. Build &amp;amp; Test
&lt;/h3&gt;

&lt;p&gt;Many existing &lt;code&gt;CreateMap()&lt;/code&gt; and &lt;code&gt;ForMember()&lt;/code&gt; configurations should require little or no modification.&lt;/p&gt;

&lt;p&gt;As with any migration, it's recommended to run your existing mapping tests to validate behavior.&lt;/p&gt;




&lt;h1&gt;
  
  
  Why I Built Twinify
&lt;/h1&gt;

&lt;p&gt;I wanted a mapper that is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open source&lt;/li&gt;
&lt;li&gt;Lightweight&lt;/li&gt;
&lt;li&gt;Easy to understand&lt;/li&gt;
&lt;li&gt;Familiar to existing AutoMapper users&lt;/li&gt;
&lt;li&gt;Built specifically for modern .NET&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rather than forcing developers to learn an entirely new API, Twinify focuses on keeping the transition intuitive while continuing to evolve with community feedback.&lt;/p&gt;




&lt;h1&gt;
  
  
  Getting Started
&lt;/h1&gt;

&lt;p&gt;📦 NuGet&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet add package Twinify
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;📖 Documentation&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/StevenKamwaza/Twinify.Docs" rel="noopener noreferrer"&gt;https://github.com/StevenKamwaza/Twinify.Docs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💻 Source Code&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/StevenKamwaza/Twinify" rel="noopener noreferrer"&gt;https://github.com/StevenKamwaza/Twinify&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;⭐ If Twinify helps your project, consider giving the repository a star and sharing your feedback. Community contributions and feature requests are always welcome.&lt;/p&gt;




&lt;h1&gt;
  
  
  Happy Coding! 🚀
&lt;/h1&gt;

&lt;p&gt;Built with ❤️ for the .NET community.&lt;/p&gt;




&lt;h2&gt;
  
  
  Share Your Thoughts
&lt;/h2&gt;

&lt;p&gt;Have questions, feature ideas, or migration feedback?&lt;/p&gt;

&lt;p&gt;Open an issue or start a discussion on GitHub—I'd love to hear how you're using Twinify in your projects.&lt;/p&gt;




&lt;h1&gt;
  
  
  Trending Hashtags
&lt;/h1&gt;

&lt;h1&gt;
  
  
  dotnet #csharp #dotnet8 #dotnet9 #dotnet10 #opensource #nuget #softwareengineering #backend #webdevelopment #cleanarchitecture #developer #coding #programming #github #aspnetcore #entityframework #architecture #productivity #developers #devcommunity #100DaysOfCode #BuildInPublic #OSS #AutoMapper #Twinify
&lt;/h1&gt;

</description>
      <category>backend</category>
      <category>dotnet</category>
      <category>opensource</category>
      <category>softwaredevelopment</category>
    </item>
  </channel>
</rss>
