<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://dspirit.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://dspirit.github.io/" rel="alternate" type="text/html" hreflang="en" /><updated>2025-05-18T15:11:28+02:00</updated><id>https://dspirit.github.io/feed.xml</id><title type="html">Wendelin Niesl</title><subtitle>Cloud Solution Architect | .NET &amp; C# | Domain-driven Design | Spotify API Integration Sharing insights and best practices in cloud architecture, DevOps, and platform engineering.</subtitle><author><name>Wendelin Niesl</name></author><entry><title type="html">Domain-Driven Design in Modern .NET Applications</title><link href="https://dspirit.github.io/architecture/dotnet/ddd/2025/05/18/domain-driven-design-dotnet.html" rel="alternate" type="text/html" title="Domain-Driven Design in Modern .NET Applications" /><published>2025-05-18T11:00:00+02:00</published><updated>2025-05-18T11:00:00+02:00</updated><id>https://dspirit.github.io/architecture/dotnet/ddd/2025/05/18/domain-driven-design-dotnet</id><content type="html" xml:base="https://dspirit.github.io/architecture/dotnet/ddd/2025/05/18/domain-driven-design-dotnet.html"><![CDATA[<h1 id="domain-driven-design-in-modern-net-applications">Domain-Driven Design in Modern .NET Applications</h1>

<p>Domain-Driven Design (DDD) has become an essential approach for building complex .NET applications. In this article, I’ll explore how DDD principles can be effectively implemented in modern .NET 8 applications, particularly in cloud-native environments.</p>

<h2 id="understanding-the-core-of-domain-driven-design">Understanding the Core of Domain-Driven Design</h2>

<p>Domain-Driven Design is more than just a technical architecture—it’s a methodology for tackling complexity in the heart of software. The approach emphasizes:</p>

<ol>
  <li><strong>A focus on the core domain and domain logic</strong></li>
  <li><strong>Basing complex designs on a model of the domain</strong></li>
  <li><strong>Collaborating with domain experts to improve the application model</strong></li>
  <li><strong>Learning through continuous iteration</strong></li>
</ol>

<h3 id="strategic-design-vs-tactical-design">Strategic Design vs. Tactical Design</h3>

<p>DDD comprises both strategic and tactical aspects:</p>

<p><strong>Strategic Design</strong> helps us understand the big picture:</p>
<ul>
  <li>Bounded Contexts</li>
  <li>Ubiquitous Language</li>
  <li>Context Mapping</li>
</ul>

<p><strong>Tactical Design</strong> provides specific implementation patterns:</p>
<ul>
  <li>Entities</li>
  <li>Value Objects</li>
  <li>Aggregates</li>
  <li>Domain Events</li>
  <li>Repositories</li>
</ul>

<h2 id="implementing-ddd-in-net-8">Implementing DDD in .NET 8</h2>

<p>.NET 8 offers several features that align well with DDD principles:</p>

<h3 id="rich-domain-models-with-records-and-pattern-matching">Rich Domain Models with Records and Pattern Matching</h3>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Value Object using records</span>
<span class="k">public</span> <span class="n">record</span> <span class="nf">Money</span><span class="p">(</span><span class="kt">decimal</span> <span class="n">Amount</span><span class="p">,</span> <span class="kt">string</span> <span class="n">Currency</span><span class="p">)</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">static</span> <span class="n">Money</span> <span class="nf">Zero</span><span class="p">(</span><span class="kt">string</span> <span class="n">currency</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="k">new</span><span class="p">(</span><span class="m">0</span><span class="p">,</span> <span class="n">currency</span><span class="p">);</span>
    
    <span class="k">public</span> <span class="n">Money</span> <span class="nf">Add</span><span class="p">(</span><span class="n">Money</span> <span class="n">other</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">Currency</span> <span class="p">!=</span> <span class="n">other</span><span class="p">.</span><span class="n">Currency</span><span class="p">)</span>
            <span class="k">throw</span> <span class="k">new</span> <span class="nf">InvalidOperationException</span><span class="p">(</span><span class="s">"Cannot add different currencies"</span><span class="p">);</span>
            
        <span class="k">return</span> <span class="k">this</span> <span class="n">with</span> <span class="p">{</span> <span class="n">Amount</span> <span class="p">=</span> <span class="n">Amount</span> <span class="p">+</span> <span class="n">other</span><span class="p">.</span><span class="n">Amount</span> <span class="p">};</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<h3 id="immutability-and-domain-events">Immutability and Domain Events</h3>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">class</span> <span class="nc">Order</span>
<span class="p">{</span>
    <span class="k">private</span> <span class="k">readonly</span> <span class="n">List</span><span class="p">&lt;</span><span class="n">OrderItem</span><span class="p">&gt;</span> <span class="n">_items</span> <span class="p">=</span> <span class="k">new</span><span class="p">();</span>
    <span class="k">private</span> <span class="k">readonly</span> <span class="n">List</span><span class="p">&lt;</span><span class="n">IDomainEvent</span><span class="p">&gt;</span> <span class="n">_events</span> <span class="p">=</span> <span class="k">new</span><span class="p">();</span>
    
    <span class="k">public</span> <span class="n">IReadOnlyCollection</span><span class="p">&lt;</span><span class="n">OrderItem</span><span class="p">&gt;</span> <span class="n">Items</span> <span class="p">=&gt;</span> <span class="n">_items</span><span class="p">.</span><span class="nf">AsReadOnly</span><span class="p">();</span>
    <span class="k">public</span> <span class="n">IReadOnlyCollection</span><span class="p">&lt;</span><span class="n">IDomainEvent</span><span class="p">&gt;</span> <span class="n">Events</span> <span class="p">=&gt;</span> <span class="n">_events</span><span class="p">.</span><span class="nf">AsReadOnly</span><span class="p">();</span>
    
    <span class="k">public</span> <span class="k">void</span> <span class="nf">AddItem</span><span class="p">(</span><span class="n">Product</span> <span class="n">product</span><span class="p">,</span> <span class="kt">int</span> <span class="n">quantity</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="c1">// Domain logic here</span>
        <span class="n">_items</span><span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="k">new</span> <span class="nf">OrderItem</span><span class="p">(</span><span class="n">product</span><span class="p">.</span><span class="n">Id</span><span class="p">,</span> <span class="n">product</span><span class="p">.</span><span class="n">Price</span><span class="p">,</span> <span class="n">quantity</span><span class="p">));</span>
        <span class="n">_events</span><span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="k">new</span> <span class="nf">OrderItemAddedEvent</span><span class="p">(</span><span class="n">Id</span><span class="p">,</span> <span class="n">product</span><span class="p">.</span><span class="n">Id</span><span class="p">,</span> <span class="n">quantity</span><span class="p">));</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<h2 id="benefits-in-cloud-native-applications">Benefits in Cloud-Native Applications</h2>

<p>When building cloud-native applications, DDD offers significant benefits:</p>

<ol>
  <li><strong>Clear boundaries for microservices</strong> - Bounded contexts provide natural service boundaries</li>
  <li><strong>Resilience</strong> - Well-defined aggregates help manage consistency</li>
  <li><strong>Scalability</strong> - Event-driven architecture enables loose coupling</li>
</ol>

<h2 id="conclusion">Conclusion</h2>

<p>Domain-Driven Design remains a powerful approach for managing complexity in modern .NET applications. By leveraging the latest features in .NET 8 and combining them with DDD principles, we can build more maintainable, flexible, and business-aligned systems.</p>

<p>In future articles, I’ll dive deeper into specific aspects of implementing DDD in cloud environments, particularly with Azure services.</p>

<hr />

<p>What aspects of Domain-Driven Design would you like to learn more about? Let me know in the comments below!</p>]]></content><author><name>Wendelin Niesl</name></author><category term="architecture" /><category term="dotnet" /><category term="ddd" /><summary type="html"><![CDATA[Domain-Driven Design in Modern .NET Applications]]></summary></entry><entry><title type="html">AOT Compilation: The Future of C# Performance</title><link href="https://dspirit.github.io/dotnet/csharp/performance/2025/05/18/aot-future-of-csharp.html" rel="alternate" type="text/html" title="AOT Compilation: The Future of C# Performance" /><published>2025-05-18T10:30:00+02:00</published><updated>2025-05-18T10:30:00+02:00</updated><id>https://dspirit.github.io/dotnet/csharp/performance/2025/05/18/aot-future-of-csharp</id><content type="html" xml:base="https://dspirit.github.io/dotnet/csharp/performance/2025/05/18/aot-future-of-csharp.html"><![CDATA[<h1 id="aot-compilation-the-future-of-c-performance">AOT Compilation: The Future of C# Performance</h1>

<p>The .NET ecosystem has undergone a significant shift in recent years: Ahead-of-Time (AOT) compilation has evolved from an experimental feature to a core component of the framework. With .NET 8 and looking ahead to .NET 9, Native AOT has become central to Microsoft’s performance strategy. In this article, we’ll explore how AOT is shaping the future of C# and what impact this has on our development practices.</p>

<h2 id="what-is-native-aot">What is Native AOT?</h2>

<p>Traditionally, .NET uses a Just-in-Time (JIT) compiler that translates Intermediate Language (IL) code into native machine code at runtime. In contrast, Native AOT compiles the entire code into native machine code during the build process, which offers several advantages:</p>

<ul>
  <li><strong>Faster startup times</strong>: No JIT compilation required at startup</li>
  <li><strong>Lower memory usage</strong>: Reduced overhead without JIT and other runtime components</li>
  <li><strong>No dependency on the .NET runtime</strong>: Self-contained applications without external runtime dependencies</li>
  <li><strong>Improved security</strong>: Smaller attack surface due to reduced runtime components</li>
</ul>

<h2 id="the-evolution-of-aot-in-net">The Evolution of AOT in .NET</h2>

<p>The journey to Native AOT has been a long one:</p>

<ol>
  <li><strong>.NET Native</strong> (2014): First AOT compilation technology for UWP apps</li>
  <li><strong>CoreRT</strong> (2016): Experimental project for AOT compilation in .NET Core</li>
  <li><strong>Mono AOT</strong>: AOT capabilities in Mono, particularly important for mobile applications</li>
  <li><strong>Native AOT in .NET 7</strong> (2022): First official support, albeit with limitations</li>
  <li><strong>.NET 8 Native AOT</strong> (2023): Significantly improved with broader API support</li>
  <li><strong>.NET 9 Preview</strong>: Further optimizations and developer experience improvements</li>
</ol>

<h2 id="practical-implications-for-c-developers">Practical Implications for C# Developers</h2>

<p>The introduction of Native AOT changes some fundamental aspects of C# development:</p>

<h3 id="1-reflection-and-dynamic-features">1. Reflection and Dynamic Features</h3>

<p>AOT requires static analysis of all code dependencies at compile time. This means that dynamic language features like reflection, dynamic assembly loading, or dynamic code generation are subject to restrictions.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Doesn't work reliably with AOT:</span>
<span class="kt">var</span> <span class="n">type</span> <span class="p">=</span> <span class="n">Type</span><span class="p">.</span><span class="nf">GetType</span><span class="p">(</span><span class="s">"Namespace.MyType"</span><span class="p">);</span>
<span class="kt">var</span> <span class="n">instance</span> <span class="p">=</span> <span class="n">Activator</span><span class="p">.</span><span class="nf">CreateInstance</span><span class="p">(</span><span class="n">type</span><span class="p">);</span>

<span class="c1">// AOT-friendly approach:</span>
<span class="kt">var</span> <span class="n">factory</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Dictionary</span><span class="p">&lt;</span><span class="kt">string</span><span class="p">,</span> <span class="n">Func</span><span class="p">&lt;</span><span class="n">IMyService</span><span class="p">&gt;&gt;</span>
<span class="p">{</span>
    <span class="p">[</span><span class="s">"Service1"</span><span class="p">]</span> <span class="p">=</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="k">new</span> <span class="nf">Service1</span><span class="p">(),</span>
    <span class="p">[</span><span class="s">"Service2"</span><span class="p">]</span> <span class="p">=</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="k">new</span> <span class="nf">Service2</span><span class="p">()</span>
<span class="p">};</span>
<span class="kt">var</span> <span class="n">service</span> <span class="p">=</span> <span class="n">factory</span><span class="p">[</span><span class="s">"Service1"</span><span class="p">]();</span>
</code></pre></div></div>

<h3 id="2-dependency-injection">2. Dependency Injection</h3>

<p>Although modern DI containers like Microsoft.Extensions.DependencyInjection work with AOT, we need to be more careful when registering and using services:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// AOT-compatible DI setup</span>
<span class="kt">var</span> <span class="n">builder</span> <span class="p">=</span> <span class="n">WebApplication</span><span class="p">.</span><span class="nf">CreateSlimBuilder</span><span class="p">(</span><span class="n">args</span><span class="p">);</span>
<span class="n">builder</span><span class="p">.</span><span class="n">Services</span><span class="p">.</span><span class="n">AddSingleton</span><span class="p">&lt;</span><span class="n">IMyService</span><span class="p">,</span> <span class="n">MyService</span><span class="p">&gt;();</span>
<span class="n">builder</span><span class="p">.</span><span class="n">Services</span><span class="p">.</span><span class="n">AddKeyedSingleton</span><span class="p">&lt;</span><span class="n">IPaymentProcessor</span><span class="p">,</span> <span class="n">StripeProcessor</span><span class="p">&gt;(</span><span class="s">"stripe"</span><span class="p">);</span>
</code></pre></div></div>

<h3 id="3-smaller-faster-applications">3. Smaller, Faster Applications</h3>

<p>The biggest advantage of AOT is the generation of smaller, faster applications. Particularly beneficial for use cases such as:</p>

<ul>
  <li>Serverless Functions (Azure Functions, AWS Lambda)</li>
  <li>Container-based microservices</li>
  <li>CLI tools</li>
  <li>Edge computing and IoT applications</li>
</ul>

<p>which benefit tremendously from reduced startup times and lower resource consumption.</p>

<h2 id="practical-example-azure-function-with-native-aot">Practical Example: Azure Function with Native AOT</h2>

<p>A simple example of an Azure Function utilizing Native AOT:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Program.cs</span>
<span class="kt">var</span> <span class="n">host</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">HostBuilder</span><span class="p">()</span>
    <span class="p">.</span><span class="nf">ConfigureFunctionsWebApplication</span><span class="p">()</span>
    <span class="p">.</span><span class="nf">Build</span><span class="p">();</span>

<span class="n">host</span><span class="p">.</span><span class="nf">Run</span><span class="p">();</span>

<span class="c1">// Function.cs</span>
<span class="k">public</span> <span class="k">class</span> <span class="nc">Function</span>
<span class="p">{</span>
    <span class="p">[</span><span class="nf">Function</span><span class="p">(</span><span class="s">"HttpExample"</span><span class="p">)]</span>
    <span class="k">public</span> <span class="n">HttpResponseData</span> <span class="nf">Run</span><span class="p">([</span><span class="nf">HttpTrigger</span><span class="p">(</span><span class="n">AuthorizationLevel</span><span class="p">.</span><span class="n">Anonymous</span><span class="p">,</span> <span class="s">"get"</span><span class="p">)]</span> <span class="n">HttpRequestData</span> <span class="n">req</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="kt">var</span> <span class="n">response</span> <span class="p">=</span> <span class="n">req</span><span class="p">.</span><span class="nf">CreateResponse</span><span class="p">(</span><span class="n">HttpStatusCode</span><span class="p">.</span><span class="n">OK</span><span class="p">);</span>
        <span class="n">response</span><span class="p">.</span><span class="nf">WriteString</span><span class="p">(</span><span class="s">"Hello from an AOT-compiled Azure Function!"</span><span class="p">);</span>
        <span class="k">return</span> <span class="n">response</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>This function starts significantly faster and consumes less memory than its JIT-compiled counterpart, which is particularly important in serverless scenarios with cold starts.</p>

<h2 id="impact-on-domain-driven-design-and-clean-architecture">Impact on Domain-Driven Design and Clean Architecture</h2>

<p>AOT reinforces the importance of a clear architecture. Domain-Driven Design with its explicit contexts and boundaries aligns perfectly with AOT requirements:</p>

<ol>
  <li><strong>Explicit dependencies</strong>: DDD promotes explicit dependencies, which facilitates static analysis for AOT</li>
  <li><strong>Reduced reflection</strong>: A well-designed domain model minimizes the need for reflection</li>
  <li><strong>Clear boundaries</strong>: Bounded contexts provide natural boundaries for compilation units</li>
</ol>

<h2 id="the-future-hybrid-approaches-and-trimming">The Future: Hybrid Approaches and Trimming</h2>

<p>The future of .NET and C# lies in a flexible combination of JIT and AOT. .NET 9 is expected to enable even more seamless transitions between these worlds and provide better trimming support to include only the library parts that are actually needed.</p>

<h2 id="conclusion">Conclusion</h2>

<p>Native AOT represents a paradigm shift in .NET development. It brings C# closer to the performance of native languages like Rust or C++ without sacrificing productivity advantages and security features. As cloud solution architects, we should keep an eye on this technology and deploy it strategically where fast startup times, low resource consumption, and strong isolation are important.</p>

<p>Although there are some trade-offs—particularly with dynamic language features—the benefits clearly outweigh them for many modern use cases. As AOT matures in upcoming .NET versions, we’ll be able to incorporate this technology more frequently in our projects.</p>

<hr />

<p>What experiences have you had with Native AOT? Have you already implemented projects with it or are you planning to use it in future applications? I look forward to your comments and experiences!</p>]]></content><author><name>Wendelin Niesl</name></author><category term="dotnet" /><category term="csharp" /><category term="performance" /><summary type="html"><![CDATA[AOT Compilation: The Future of C# Performance]]></summary></entry></feed>