<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[C# Dotnet .Net Azure Sql Programming .NetCore]]></title><description><![CDATA[Blog on Programming, .Net, C#, .NetCore]]></description><link>https://dotdev.com.tr</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1671995197539/pt7nvDhly.png</url><title>C# Dotnet .Net Azure Sql Programming .NetCore</title><link>https://dotdev.com.tr</link></image><generator>RSS for Node</generator><lastBuildDate>Sat, 06 Jun 2026 16:32:02 GMT</lastBuildDate><atom:link href="https://dotdev.com.tr/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Performance Improvements in .NET 8, ASP.NET Core, and .NET MAUI | .NET Conf 2023]]></title><description><![CDATA[Reference
https://www.youtube.com/watch?v=YiOkz1x2qaE&list=PLdo4fOcmZ0oULyHSPBx-tQzePOYlhvrAU&index=21
https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-8/]]></description><link>https://dotdev.com.tr/performance-improvements-in-net-8-aspnet-core-and-net-maui-net-conf-2023</link><guid isPermaLink="true">https://dotdev.com.tr/performance-improvements-in-net-8-aspnet-core-and-net-maui-net-conf-2023</guid><category><![CDATA[.net 8]]></category><dc:creator><![CDATA[İbrahim Uludağ]]></dc:creator><pubDate>Wed, 27 Dec 2023 11:19:01 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/lUaaKCUANVI/upload/4a07684646e3e9d25fbb814dd1989137.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1703674099391/40869849-1fef-4e5b-bb86-86a33c63c797.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1703674121193/5b9bab77-b03e-4463-90a3-8e92c8dce679.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1703674152767/3b2eb553-1fb8-439e-b7bd-d1d2d4e5b847.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1703674174619/348338e5-8cd6-4a99-849d-aa4bb7d7ef77.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1703674393678/3ba4c03f-ed21-48b1-8179-c32409051ecd.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1703674602682/c63ea8f3-c0fe-416d-b1ce-d8edb941695e.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1703674762281/ba05bf00-7bfe-42a0-9b50-cf62509a1acf.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1703674914951/244028a2-0a7f-4e66-accc-c54041fba836.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1703675123312/da62637b-fdd4-46ed-9030-018bb240ce66.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1703675279522/5ba9bbe9-5e45-40ae-b9b2-cf39020aeacf.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1703675456258/90813fa1-6ab0-4992-a3c3-c83729a0909a.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1703675672299/4495dc19-a799-43a7-8e53-21d7c2af545b.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-reference">Reference</h2>
<p><a target="_blank" href="https://www.youtube.com/watch?v=YiOkz1x2qaE&amp;list=PLdo4fOcmZ0oULyHSPBx-tQzePOYlhvrAU&amp;index=21">https://www.youtube.com/watch?v=YiOkz1x2qaE&amp;list=PLdo4fOcmZ0oULyHSPBx-tQzePOYlhvrAU&amp;index=21</a></p>
<p><a target="_blank" href="https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-8/">https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-8/</a></p>
]]></content:encoded></item><item><title><![CDATA[Tiny, fast ASP.NET Core APIs with native AOT | .NET Conf 2023]]></title><description><![CDATA[.NET 8 introduces support for publishing ASP.NET Core applications to native AOT for lightning-fast startup times & small, self-contained, native executables & containers. This session will provide an overview of when you might want to consider publi...]]></description><link>https://dotdev.com.tr/tiny-fast-aspnet-core-apis-with-native-aot-net-conf-2023</link><guid isPermaLink="true">https://dotdev.com.tr/tiny-fast-aspnet-core-apis-with-native-aot-net-conf-2023</guid><category><![CDATA[.NET]]></category><category><![CDATA[.net 8]]></category><dc:creator><![CDATA[İbrahim Uludağ]]></dc:creator><pubDate>Fri, 22 Dec 2023 17:39:06 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/xG8IQMqMITM/upload/e0744f9e2539776b5fe03bcf99ad072e.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>.NET 8 introduces support for publishing <a target="_blank" href="http://ASP.NET">ASP.NET</a> Core applications to native AOT for lightning-fast startup times &amp; small, self-contained, native executables &amp; containers. This session will provide an overview of when you might want to consider publishing native AOT for your <a target="_blank" href="http://ASP.NET">ASP.NET</a> Core APIs and demonstrate the benefits and compatibility considerations.</p>
<h1 id="heading-why-aot">Why AOT?</h1>
<ul>
<li><p>Smaller apps</p>
</li>
<li><p>Faster startups</p>
</li>
<li><p>Less memory usage</p>
</li>
</ul>
<h1 id="heading-demo">Demo</h1>
<p>Create a new <a target="_blank" href="https://github.com/ibrahimuludag/native-aot/commit/d541c8c1b5f48abc3f7323b5d4f6384906fbdc0f">Api Project</a> and publish. The output is as below.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1703264503202/3aa52b4f-ada4-4d18-9c6e-282e687e30cd.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-self-contained-deployment">Self Contained Deployment</h2>
<p>By default, the output is framework-dependent. If you want your output independent of the running environment, you may use self-contained. This will include the framework.</p>
<p>Output will include the framework runtime which makes the size very large.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1703264926645/c117eb2a-900b-42ed-971a-35143152b6f3.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-how-will-native-aot-will-help">How will Native AOT Will Help?</h2>
<p>Enable Nati AOT by adding below to csproj.</p>
<pre><code class="lang-csharp">&lt;PublishAot&gt;<span class="hljs-literal">true</span>&lt;/PublishAot&gt;
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1703264984366/4a6dacf0-ad7c-4670-8f27-2b450885aaf6.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1703265169966/4f7f76bd-75a2-4147-8b48-af834f2609c6.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1703265673197/5983bc49-cc75-489d-8a73-03ee24bbd835.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-webapplicationcreateslimbuilder">WebApplication.CreateSlimBuilder()</h2>
<p>It has fewer defaults and is lighter. Use with Native AOT.</p>
<p>The output will have approximately 10 MB for Windows.</p>
<h2 id="heading-webapplicationcreateemptybuilder">WebApplication.CreateEmptyBuilder()</h2>
<p>It creates an empty builder but you need to configure what you need. The output will be smaller.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1703266491973/a37dbe8a-77e4-4528-a37a-9e47efc07a02.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1703266692682/c089816e-4473-4131-adb3-b82e36143fc1.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1703266712434/dc46d801-f69d-4a0a-94ce-e6fdfd1e13c1.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-reference">Reference</h2>
<p><a target="_blank" href="https://www.youtube.com/watch?v=FpQXyFoZ9aY&amp;list=PLdo4fOcmZ0oULyHSPBx-tQzePOYlhvrAU&amp;index=20">https://www.youtube.com/watch?v=FpQXyFoZ9aY&amp;list=PLdo4fOcmZ0oULyHSPBx-tQzePOYlhvrAU&amp;index=20</a></p>
]]></content:encoded></item><item><title><![CDATA[.NET Configuration In Depth | .NET Conf 2023]]></title><description><![CDATA[This is my notes for the .NET Configuration In Depth | .NET Conf 2023
What is Configuration

Settings

Retry Times

Queue Length



Feature Flags

Per User

Percentage



Secrets

Connection String



When the Configuration is Applied

Compile Time

...]]></description><link>https://dotdev.com.tr/net-configuration-in-depth-net-conf-2023</link><guid isPermaLink="true">https://dotdev.com.tr/net-configuration-in-depth-net-conf-2023</guid><category><![CDATA[.NET]]></category><category><![CDATA[asp.net core]]></category><dc:creator><![CDATA[İbrahim Uludağ]]></dc:creator><pubDate>Fri, 22 Dec 2023 00:03:17 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/D-qq7W751vs/upload/eaae4302d81a2b317882de27bbc9fde9.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This is my notes for the .NET Configuration In Depth | .NET Conf 2023</p>
<h2 id="heading-what-is-configuration">What is Configuration</h2>
<ul>
<li><p>Settings</p>
<ul>
<li><p>Retry Times</p>
</li>
<li><p>Queue Length</p>
</li>
</ul>
</li>
<li><p>Feature Flags</p>
<ul>
<li><p>Per User</p>
</li>
<li><p>Percentage</p>
</li>
</ul>
</li>
<li><p>Secrets</p>
<ul>
<li>Connection String</li>
</ul>
</li>
</ul>
<h2 id="heading-when-the-configuration-is-applied">When the Configuration is Applied</h2>
<ul>
<li><p>Compile Time</p>
</li>
<li><p>Run Time</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1703199797831/6bc768cc-72c9-4763-bc44-f72bfc50ee62.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1703199840780/bb2681e9-7f35-48fc-b7f2-d150a4e9eb84.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1703199861594/e554954e-0927-44f8-9b52-da868402f018.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1703199881310/3777912d-5ab2-407e-a407-89221f84a932.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1703199923576/36b42c45-7b60-43ee-9d17-75627c4dca9e.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1703199963171/a3413e26-d221-475b-a7a2-5b97be21ae09.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-options-pattern">Options Pattern</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1703202451671/5459fbf7-b3e9-4a9b-9a08-927d1faf555c.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1703202483083/7c195227-961f-4711-9e4d-42ea0c4bfe0c.png" alt class="image--center mx-auto" /></p>
<p>Github Repo: <a target="_blank" href="https://github.com/ibrahimuludag/aspnetcore-configuration">https://github.com/ibrahimuludag/aspnetcore-configuration</a></p>
<h3 id="heading-reference">Reference</h3>
<p><a target="_blank" href="https://www.youtube.com/watch?v=aOXaBZFB0-0&amp;list=PLdo4fOcmZ0oULyHSPBx-tQzePOYlhvrAU&amp;index=15&amp;t=26s">https://www.youtube.com/watch?v=aOXaBZFB0-0&amp;list=PLdo4fOcmZ0oULyHSPBx-tQzePOYlhvrAU&amp;index=15&amp;t=26s</a></p>
]]></content:encoded></item><item><title><![CDATA[Source Generators]]></title><description><![CDATA[Source Generators are part of Roslyn feature that automatically generates code during the compilation process.

Why Source Generators

Alternatıve to Reflection

It is compile time not runtime

Unblock AOT trimming

It is just code




Demo
The code ...]]></description><link>https://dotdev.com.tr/source-generators</link><guid isPermaLink="true">https://dotdev.com.tr/source-generators</guid><category><![CDATA[C#]]></category><category><![CDATA[sourcegenerators]]></category><dc:creator><![CDATA[İbrahim Uludağ]]></dc:creator><pubDate>Wed, 13 Dec 2023 22:55:24 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/nyL-rzwP-Mk/upload/81f953c418d74d066dcf1fe546b892a1.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Source Generators are part of Roslyn feature that automatically generates code during the compilation process.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1702498751392/b4c9b294-3aa8-4628-b17d-b1a9c8c07c80.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-why-source-generators">Why Source Generators</h1>
<ul>
<li><p>Alternatıve to Reflection</p>
<ul>
<li><p>It is compile time not runtime</p>
</li>
<li><p>Unblock AOT trimming</p>
</li>
<li><p>It is just code</p>
</li>
</ul>
</li>
</ul>
<h1 id="heading-demo">Demo</h1>
<p>The code produces the below output.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1702500267408/ee3d9bc1-e639-4ed3-a4cd-745d23ee5b24.png" alt class="image--center mx-auto" /></p>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Main</span>(<span class="hljs-params"><span class="hljs-keyword">string</span>[] args</span>)</span>
{
    <span class="hljs-keyword">var</span> classTypes = Assembly.GetEntryAssembly()
        .GetTypes()
        .Where(c =&gt; c.IsClass &amp;&amp; c.IsPublic)
        .Select(c =&gt; c.FullName);

    <span class="hljs-keyword">foreach</span> (<span class="hljs-keyword">var</span> classType <span class="hljs-keyword">in</span> classTypes)
    {
        Console.WriteLine(classType);
    }
}
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1702499933374/0397e76f-f302-4410-bcd7-762f8caac48a.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-publishaot">PublishAot</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1702500409738/4b7d87ab-cd85-4062-9dba-25e339f43700.png" alt class="image--center mx-auto" /></p>
<p>If you have enabled PublishAot, it will publish to machine code and remove all unused references. Since our classes (Student, Course) are not reference, they will no be included in the published code and the output will be empty.</p>
<h1 id="heading-creating-source-generator">Creating Source Generator</h1>
<p>To use Source Generator, the project must target netstandard2.0. So, create a new class library with netstandard2.0.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1702500923738/f623020d-8970-4ff8-bae0-c958a93075b2.png" alt class="image--center mx-auto" /></p>
<p>Add reference for the below packages.</p>
<pre><code class="lang-csharp">Microsoft.CodeAnalysis.Analyzers
Microsoft.CodeAnalysis.CSharp
</code></pre>
<p>Add the reference as below</p>
<pre><code class="lang-csharp">    &lt;ProjectReference Include=<span class="hljs-string">"..\Generator\Generator.csproj"</span> OutputItemType=<span class="hljs-string">"Analyzer"</span> /&gt;
</code></pre>
<p>Make the changes in the Generator class.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">namespace</span> <span class="hljs-title">Generator</span>;

[<span class="hljs-meta">Generator</span>]
<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">TheGenerator</span> : <span class="hljs-title">IIncrementalGenerator</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Initialize</span>(<span class="hljs-params">IncrementalGeneratorInitializationContext context</span>)</span>
    {
        <span class="hljs-keyword">var</span> provider = context.SyntaxProvider.CreateSyntaxProvider(
            predicate: <span class="hljs-keyword">static</span>(node, _) =&gt; node <span class="hljs-keyword">is</span> ClassDeclarationSyntax,
            transform: <span class="hljs-keyword">static</span> (ctx, _) =&gt; (ClassDeclarationSyntax)ctx.Node
            ).Where(c =&gt; c <span class="hljs-keyword">is</span> not <span class="hljs-literal">null</span>);

        <span class="hljs-keyword">var</span> compilation = context.CompilationProvider.Combine(provider.Collect());

        context.RegisterSourceOutput(compilation, Execute);
    }

    <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Execute</span>(<span class="hljs-params">SourceProductionContext context, (Compilation Left, ImmutableArray&lt;ClassDeclarationSyntax&gt; Right</span>) tuple)</span>
    {
        <span class="hljs-keyword">var</span> (compilation, list) = tuple;

        <span class="hljs-keyword">var</span> namelist = <span class="hljs-keyword">new</span> List&lt;<span class="hljs-keyword">string</span>&gt;();

        <span class="hljs-keyword">foreach</span> (<span class="hljs-keyword">var</span> systax <span class="hljs-keyword">in</span> list) {
            <span class="hljs-keyword">var</span> symbol = compilation.GetSemanticModel(systax.SyntaxTree)
                .GetDeclaredSymbol(systax) <span class="hljs-keyword">as</span> INamedTypeSymbol;

            namelist.Add(<span class="hljs-string">$"\"<span class="hljs-subst">{symbol.ToDisplayString()}</span>\""</span>);
        }

        <span class="hljs-keyword">var</span> names = <span class="hljs-keyword">string</span>.Join(<span class="hljs-string">",\n "</span>, namelist);

        <span class="hljs-keyword">var</span> theCode = $<span class="hljs-string">$""</span><span class="hljs-string">"
            namespace  Generator;

            public static class ClassNames {
                public static List&lt;string&gt; Names = new(){
                    {{ names }}
                };
            }
            "</span><span class="hljs-string">""</span>;

        context.AddSource(<span class="hljs-string">"YourClassList.g.cs"</span>, theCode);
    }
}
</code></pre>
<h2 id="heading-reference">Reference</h2>
<p><a target="_blank" href="https://www.youtube.com/watch?v=Yf8t7GqA6zA&amp;list=PLdo4fOcmZ0oULyHSPBx-tQzePOYlhvrAU&amp;index=11">https://www.youtube.com/watch?v=Yf8t7GqA6zA&amp;list=PLdo4fOcmZ0oULyHSPBx-tQzePOYlhvrAU&amp;index=11</a></p>
<p><a target="_blank" href="https://github.com/ibrahimuludag/sourcegenerator">https://github.com/ibrahimuludag/sourcegenerator</a></p>
]]></content:encoded></item><item><title><![CDATA[Vertical Slice Architecture: How Does it Compare to Clean Architecture]]></title><description><![CDATA[This is the summary of the presentation.
No Architecture

Pros

Little or no abstraction

Quick to build early - go from nothing deployed

Potential for performance due to tight coupling & less abstraction


Cons

As the size of the system increases ...]]></description><link>https://dotdev.com.tr/vertical-slice-architecture-how-does-it-compare-to-clean-architecture</link><guid isPermaLink="true">https://dotdev.com.tr/vertical-slice-architecture-how-does-it-compare-to-clean-architecture</guid><category><![CDATA[.NET]]></category><dc:creator><![CDATA[İbrahim Uludağ]]></dc:creator><pubDate>Tue, 12 Dec 2023 20:08:16 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/B8ZFV4E0YOw/upload/0185a649c6e6b96d9d947c32da16325f.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This is the summary of the <a target="_blank" href="https://www.youtube.com/watch?v=T-EwN9UqRwE&amp;list=PLdo4fOcmZ0oULyHSPBx-tQzePOYlhvrAU&amp;index=17">presentation</a>.</p>
<h1 id="heading-no-architecture">No Architecture</h1>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1702408446786/bff7d8f7-7872-4e35-9262-a1ea4a854127.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-pros">Pros</h2>
<ul>
<li><p>Little or no abstraction</p>
</li>
<li><p>Quick to build early - go from nothing deployed</p>
</li>
<li><p>Potential for performance due to tight coupling &amp; less abstraction</p>
</li>
</ul>
<h2 id="heading-cons">Cons</h2>
<ul>
<li><p>As the size of the system increases so does the time to develop</p>
</li>
<li><p>Difficult for multiple teams to work on the same codebase</p>
</li>
<li><p>Technology changes or breaks impact the whole system</p>
</li>
<li><p>Difficult to test</p>
</li>
</ul>
<h1 id="heading-n-tier">N-Tier</h1>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1702409551396/cec40852-f35b-41ba-925a-42ea53197232.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-pros-1">Pros</h2>
<ul>
<li><p>Fairly intuitive abstraction to start</p>
</li>
<li><p>Reasonably quick to build</p>
</li>
<li><p>Improved testability</p>
</li>
</ul>
<h2 id="heading-cons-1">Cons</h2>
<ul>
<li><p>As the size of the system increases so does the time to develop</p>
</li>
<li><p>Difficult for multiple teams to work on the same codebase</p>
</li>
<li><p>Technology changes or breaks impact the whole system</p>
</li>
</ul>
<h1 id="heading-clean-architecture">Clean Architecture</h1>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1702409721133/8bed8ce7-d8a5-4721-8087-530f627728e8.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1702409982808/d6b80907-f49e-45f8-a817-1782997dbc42.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-pros-2">Pros</h2>
<ul>
<li><p>Highly abstracted for larger systems</p>
</li>
<li><p>Resilient to technology changes</p>
</li>
<li><p>Very testable</p>
</li>
<li><p>Not influenced by anything external</p>
</li>
<li><p>Consistent velocity</p>
</li>
<li><p>Easy to work on by a few teams</p>
</li>
</ul>
<h2 id="heading-cons-2">Cons</h2>
<ul>
<li><p>Higher barrier to entry</p>
</li>
<li><p>Depends on training &amp; a disciplined team to utilize it well</p>
</li>
<li><p>Slower development time overall</p>
</li>
<li><p>Lots of code to write a simple feature</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1702411018870/c0652c02-c5a9-4924-a4c8-c671a30ebc8a.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-vertical-slice-architecture">Vertical Slice Architecture</h1>
<h2 id="heading-proximity-principle">Proximity Principle</h2>
<p>Code that is changed together should live together.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1702411159442/b34b4bc6-b141-43c5-a238-7a4c34918f3c.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1702411179448/45e4e1c7-adbf-42b5-8c4e-dc04ad656ad4.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-pros-3">Pros</h2>
<ul>
<li><p>Little to no abstraction</p>
</li>
<li><p>Low barrier to entry</p>
</li>
<li><p>Resilient to technology changes</p>
</li>
<li><p>The level of testability can be per feature</p>
</li>
<li><p>Easy to work on by many teams</p>
</li>
<li><p>Feature changes have no impact on other features</p>
</li>
</ul>
<h2 id="heading-cons-3">Cons</h2>
<ul>
<li><p>Requires contracts &amp; messaging when working in a larger-scale system</p>
</li>
<li><p>Hard to decide what to have as Shared Code vs Feature Code</p>
</li>
<li><p>Each feature can be written in a different way leading to cognitive load when switching</p>
</li>
</ul>
<h2 id="heading-reference">Reference</h2>
<p><a target="_blank" href="https://www.youtube.com/watch?v=T-EwN9UqRwE&amp;list=PLdo4fOcmZ0oULyHSPBx-tQzePOYlhvrAU&amp;index=17">https://www.youtube.com/watch?v=T-EwN9UqRwE&amp;list=PLdo4fOcmZ0oULyHSPBx-tQzePOYlhvrAU&amp;index=17</a></p>
]]></content:encoded></item><item><title><![CDATA[Building Cloud Native apps with .NET 8 | .NET Conf 2023]]></title><description><![CDATA[.Net Cloud Native
.Net has had the aspirational goal of being the most productive platform for building Cloud Native apps for some time.

Health Checks

Kestrel

HTTP Client Factory

Polly


gRPC

YARP

Container Builds

Native AOT


Running distribu...]]></description><link>https://dotdev.com.tr/building-cloud-native-apps-with-net-8-net-conf-2023</link><guid isPermaLink="true">https://dotdev.com.tr/building-cloud-native-apps-with-net-8-net-conf-2023</guid><dc:creator><![CDATA[İbrahim Uludağ]]></dc:creator><pubDate>Sun, 10 Dec 2023 18:00:06 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/2JIvboGLeho/upload/47c86d8bbd5a08d6b63135c1e2b88b91.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-net-cloud-native">.Net Cloud Native</h1>
<p>.Net has had the aspirational goal of being the most productive platform for building Cloud Native apps for some time.</p>
<ul>
<li><p>Health Checks</p>
</li>
<li><p>Kestrel</p>
</li>
<li><p>HTTP Client Factory</p>
<ul>
<li>Polly</li>
</ul>
</li>
<li><p>gRPC</p>
</li>
<li><p>YARP</p>
</li>
<li><p>Container Builds</p>
</li>
<li><p>Native AOT</p>
</li>
</ul>
<p>Running distributed applications locally is very hard. Microsoft has developed .Net Aspire for this purpose.</p>
<h1 id="heading-net-aspire">.Net Aspire</h1>
<ul>
<li><p>.Net Aspire is a stack for building resilient, observable, and configurable cloud-native applications for .NET</p>
</li>
<li><p>.Net Aspire includes a curated set of components enhanced for cloud-native fundamentals including Telemetry, Resilience, Configuration, Health Checks, and Composition</p>
</li>
<li><p>.Net Aspire makes it easy to discover, acquire, and configure essential dependencies for cloud-native applications on day 1 and day 100</p>
</li>
</ul>
<h1 id="heading-setup">Setup</h1>
<p>To work with .NET Aspire, you'll need the following installed locally:</p>
<ul>
<li><p><a target="_blank" href="https://dotnet.microsoft.com/download/dotnet/8.0">.NET 8.0</a></p>
</li>
<li><p><a target="_blank" href="https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-workload-install">.NET Aspire workload</a></p>
</li>
<li><p><a target="_blank" href="https://www.docker.com/products/docker-desktop/">Docker Desktop</a></p>
</li>
<li><p>Integrated Developer Environment (IDE) or code editor, such as:</p>
<ul>
<li><p><a target="_blank" href="https://visualstudio.microsoft.com/vs/preview/">Visual Studio 2022 Preview</a> version 17.9 or higher (Optional)</p>
</li>
<li><p><a target="_blank" href="https://code.visualstudio.com/">Visual Studio Code</a> (Optional)</p>
</li>
</ul>
</li>
</ul>
<h1 id="heading-demo">Demo</h1>
<p><a target="_blank" href="https://www.youtube.com/watch?v=z1M-7Bms1Jg&amp;list=PLdo4fOcmZ0oULyHSPBx-tQzePOYlhvrAU&amp;index=4">https://www.youtube.com/watch?v=z1M-7Bms1Jg&amp;list=PLdo4fOcmZ0oULyHSPBx-tQzePOYlhvrAU&amp;index=4</a></p>
<h2 id="heading-reference">Reference</h2>
<ul>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=z1M-7Bms1Jg&amp;list=PLdo4fOcmZ0oULyHSPBx-tQzePOYlhvrAU&amp;index=4">https://www.youtube.com/watch?v=z1M-7Bms1Jg&amp;list=PLdo4fOcmZ0oULyHSPBx-tQzePOYlhvrAU&amp;index=4</a></p>
</li>
<li><p><a target="_blank" href="https://learn.microsoft.com/en-us/dotnet/aspire/fundamentals/setup-tooling?tabs=visual-studio#install-net-aspire">https://learn.microsoft.com/en-us/dotnet/aspire/fundamentals/setup-tooling?tabs=visual-studio#install-net-aspire</a></p>
</li>
<li><p><a target="_blank" href="https://learn.microsoft.com/en-us/dotnet/aspire/fundamentals/setup-tooling?tabs=visual-studio">https://learn.microsoft.com/en-us/dotnet/aspire/fundamentals/setup-tooling?tabs=visual-studio</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[.NET Containers advancements in .NET 8]]></title><description><![CDATA[This is a summary of .NET Containers advancements in .NET 8 on .Net Conf 2023.
It is requied from communitity for .Net Container Images to be

Small (registry pull faster)

Secure (non-root; no shell or package manager)

Compliant (minimal dependenci...]]></description><link>https://dotdev.com.tr/net-containers-advancements-in-net-8</link><guid isPermaLink="true">https://dotdev.com.tr/net-containers-advancements-in-net-8</guid><category><![CDATA[.net 8]]></category><category><![CDATA[Docker]]></category><dc:creator><![CDATA[İbrahim Uludağ]]></dc:creator><pubDate>Thu, 07 Dec 2023 20:12:52 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1701980342148/2d390ade-ba05-4088-b3f2-c853685ed1d1.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This is a summary of <a target="_blank" href="https://www.youtube.com/watch?v=scIAwLrruMY&amp;list=PLdo4fOcmZ0oULyHSPBx-tQzePOYlhvrAU&amp;index=14&amp;t=10s">.NET Containers advancements in .NET 8</a> on .Net Conf 2023.</p>
<p>It is requied from communitity for .Net Container Images to be</p>
<ul>
<li><p>Small (registry pull faster)</p>
</li>
<li><p>Secure (non-root; no shell or package manager)</p>
</li>
<li><p>Compliant (minimal dependencies, easy audit)</p>
</li>
<li><p>Composable (e.g. add locallication when needed)</p>
</li>
<li><p>Compatible (glibc vs musl libc)</p>
</li>
<li><p>Supported (part of a support contract / lifecycle)</p>
</li>
</ul>
<h2 id="heading-ubuntu-chiseled-net-images">Ubuntu Chiseled .NET images</h2>
<p>Ubuntu Chiseled .NET images are a type of "distroless" container image that contain only the minimal set of packages .NET needs, with everything else removed. These images offer dramatically smaller deployment sizes and attack surface by including only the minimal set of packages required to run .NET applications.</p>
<p>Please see the <a target="_blank" href="https://github.com/dotnet/dotnet-docker/blob/main/documentation/ubuntu-chiseled.md">Ubuntu Chiseled + .NET</a> documentation page for more info.</p>
<h2 id="heading-container-size-improvements">Container Size Improvements</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701976490720/42d677c7-0ee3-4b27-8e90-1478dee6315c.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-net-containers-in-general">.Net Containers in General</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701976578218/f5073c06-a2bb-494d-9f30-0481f889102a.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-how-to-publish-your-application">How to Publish Your Application?</h2>
<p>First add the below package from Nuget.</p>
<pre><code class="lang-markdown">dotnet add package Microsoft.NET.Build.Containers --version 8.0.100
</code></pre>
<p>Then, publish your container using .NET CLI. I am using -<code>r linux-x64</code>, because I am on Windows.</p>
<pre><code class="lang-markdown">dotnet publish -t:PublishContainer -r linux-x64
</code></pre>
<p>Then your application is published as a container to your local registry without any Dockerfile as below.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701977850910/5efd18a3-3897-4748-9311-c7f3e7f934a4.png" alt class="image--center mx-auto" /></p>
<p>However, the size of the image will be big. We need to shrink the size of the container.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701978004011/8bc08f72-65b6-47f8-8120-4942bcd202c2.png" alt class="image--center mx-auto" /></p>
<p>To shrink, add the <code>PublishTrimmed and ContainerFamily</code> to your csproj file.</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">PropertyGroup</span>&gt;</span>
....
    <span class="hljs-tag">&lt;<span class="hljs-name">PublishTrimmed</span>&gt;</span>true<span class="hljs-tag">&lt;/<span class="hljs-name">PublishTrimmed</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">ContainerFamily</span>&gt;</span>jammy-chiseled<span class="hljs-tag">&lt;/<span class="hljs-name">ContainerFamily</span>&gt;</span>
....
<span class="hljs-tag">&lt;<span class="hljs-name">PropertyGroup</span>&gt;</span>
</code></pre>
<p>Then publish your project again.</p>
<pre><code class="lang-markdown">dotnet publish -t:PublishContainer -r linux-x64 -p ContainerImageTag=chiseled
</code></pre>
<p>You will see that the size is reduced now.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1701978956025/5a880caf-a0fa-48af-841d-d79fa8c2697a.png" alt class="image--center mx-auto" /></p>
<p>You can also publish your app as <a target="_blank" href="https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/?tabs=net7%2Cwindows">Native AOT</a>. Add the below to your csproj file.</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">PublishAot</span>&gt;</span>True<span class="hljs-tag">&lt;/<span class="hljs-name">PublishAot</span>&gt;</span>
</code></pre>
<pre><code class="lang-markdown">dotnet publish -t:PublishContainer -r linux-x64 -p ContainerImageTag=aot
</code></pre>
<p>You can also specify the base image for the container.</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">ContainerBaseImage</span>&gt;</span>mcr.microsoft.com/dotnet/nightly/runtime:8.0<span class="hljs-tag">&lt;/<span class="hljs-name">ContainerBaseImage</span>&gt;</span>
</code></pre>
<p>I believe that creating containers without Dockerfile is a life-saving feature for developers. You can check the <a target="_blank" href="https://learn.microsoft.com/en-us/dotnet/core/docker/publish-as-container?pivots=dotnet-8-0">documentation</a> for more information.</p>
]]></content:encoded></item><item><title><![CDATA[New Data Annotations in .NET 8]]></title><description><![CDATA[System.ComponentModel.DataAnnotations provides attribute classes that are used to define metadata for ASP.NET MVC and ASP.NET data controls.
The namespace has new annotations and modifications to existing ones on .NET8. Let's review those. Also, you ...]]></description><link>https://dotdev.com.tr/new-data-annotations-in-net-8</link><guid isPermaLink="true">https://dotdev.com.tr/new-data-annotations-in-net-8</guid><category><![CDATA[C#]]></category><category><![CDATA[.net 8]]></category><dc:creator><![CDATA[İbrahim Uludağ]]></dc:creator><pubDate>Wed, 06 Dec 2023 21:39:45 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1701980370295/681eedf5-b45b-4d8a-aa92-58a9483c2037.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>System.ComponentModel.DataAnnotations provides attribute classes that are used to define metadata for <a target="_blank" href="http://ASP.NET">ASP.NET</a> MVC and <a target="_blank" href="http://ASP.NET">ASP.NET</a> data controls.</p>
<p>The namespace has new annotations and modifications to existing ones on .NET8. Let's review those. Also, you can find a working sample project on my <a target="_blank" href="https://github.com/ibrahimuludag/dataannotations">Github Repo</a>.</p>
<h2 id="heading-length">Length</h2>
<p>Specifies the minimum and maximum length of collection/string data allowed in a property.</p>
<pre><code class="lang-csharp">[<span class="hljs-meta">Length(1, 20)</span>]
<span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> FirstName { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

[<span class="hljs-meta">Length(1, 5)</span>]
<span class="hljs-keyword">public</span> List&lt;<span class="hljs-keyword">string</span>&gt; Courses { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
</code></pre>
<h2 id="heading-range">Range</h2>
<p>Specifies the numeric range constraints for the value of a data field. Now, you can specify whether the range values are inclusive or exclusive.</p>
<ul>
<li><p><strong>MinimumIsExclusive</strong> : Specifies whether validation should fail for values that are equal to Minimum.</p>
</li>
<li><p><strong>MaximumIsExclusive</strong> : Specifies whether validation should fail for values that are equal to Maximum.</p>
</li>
</ul>
<pre><code class="lang-csharp">[<span class="hljs-meta">Range(15, 25, MinimumIsExclusive = true, MaximumIsExclusive = true)</span>]
<span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> Age { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
</code></pre>
<h2 id="heading-allowedvalues">AllowedValues</h2>
<p>Specifies a list of values that should be allowed in a property.</p>
<pre><code class="lang-csharp">[<span class="hljs-meta">AllowedValues(<span class="hljs-meta-string">"Freshman"</span>, <span class="hljs-meta-string">"Sophomore"</span>, <span class="hljs-meta-string">"Junior"</span>, <span class="hljs-meta-string">"Senior"</span>)</span>]
<span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Grade { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
</code></pre>
<h1 id="heading-deniedvalues"><strong>DeniedValues</strong></h1>
<p>Specifies a list of values that should not be allowed in a property.</p>
<pre><code class="lang-csharp">[<span class="hljs-meta">DeniedValues(<span class="hljs-meta-string">"123456"</span>, <span class="hljs-meta-string">"qwerty"</span>)</span>]
<span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Password { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
</code></pre>
<h1 id="heading-base64string"><strong>Base64String</strong></h1>
<p>Specifies that a data field value is a well-formed Base64 string.</p>
<pre><code class="lang-csharp">[<span class="hljs-meta">Base64String</span>]
<span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Hash { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
</code></pre>
<h2 id="heading-required">Required</h2>
<p>From the blogs, I see that RequiredAttribute has a new property, DisallowAllDefaultValues to exclude default values. However, I cannot see this new feature in the code and documentation. I guess, this was remove in the release.</p>
<h1 id="heading-reference">Reference</h1>
<p><a target="_blank" href="https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.dataannotations?view=net-8.0">https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.dataannotations?view=net-8.0</a></p>
]]></content:encoded></item><item><title><![CDATA[AZ-400: Designing and Implementing Microsoft DevOps Solutions Notes]]></title><description><![CDATA[These are my notes while preparing AZ-400 exam.
Site Reliability Engineering
Reliability is the ability of a system or component to perform its intended function under specified conditions for an extended period without failure. A reliable product ha...]]></description><link>https://dotdev.com.tr/az-400-designing-and-implementing-microsoft-devops-solutions-notes</link><guid isPermaLink="true">https://dotdev.com.tr/az-400-designing-and-implementing-microsoft-devops-solutions-notes</guid><category><![CDATA[Azure]]></category><category><![CDATA[notes]]></category><dc:creator><![CDATA[İbrahim Uludağ]]></dc:creator><pubDate>Tue, 15 Aug 2023 13:18:30 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1692105593421/d003ade5-aca2-4d12-9140-9e0a70ad5d98.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>These are my notes while preparing AZ-400 exam.</p>
<h1 id="heading-site-reliability-engineering">Site Reliability Engineering</h1>
<p><strong>Reliability</strong> is the ability of a system or component to perform its intended function under specified conditions for an extended period without failure. A reliable product has a high probability of performing as expected over time. The reliability of a product can be measured by how long it will last before failing and how often it fails.</p>
<ul>
<li><p>Availability</p>
</li>
<li><p>Performance</p>
</li>
<li><p>Latency</p>
</li>
<li><p>Security</p>
</li>
</ul>
<h2 id="heading-measuring-reliability">Measuring Reliability</h2>
<p><strong>SLA:</strong> Service Level Agreement</p>
<p>The agreement made with customers about how available the system is</p>
<p><strong>SLO:</strong> Service Level Objective</p>
<p>The goal that the service wants to reach or meet agreements</p>
<p><strong>SLI:</strong> Service Level Indicators</p>
<p>Actual service metric behind the commitments</p>
<h2 id="heading-why-sre">Why SRE?</h2>
<ul>
<li><p>Ownership</p>
</li>
<li><p>Work Silos</p>
</li>
<li><p>Full Stack</p>
</li>
</ul>
<h2 id="heading-key-concepts">Key Concepts</h2>
<ul>
<li><p>Feedback</p>
</li>
<li><p>Measure everything</p>
</li>
<li><p>Alert</p>
</li>
<li><p>Automate</p>
</li>
<li><p>Small changes (often)</p>
</li>
<li><p>Embrace Risk</p>
</li>
</ul>
<p>Devops focuses on development, SRE focuses on production.</p>
<h1 id="heading-azure-monitor">Azure Monitor</h1>
<p><strong>Azure Monitor</strong> is a comprehensive monitoring solution for collecting, analyzing, and responding to monitoring data from your cloud and on-premises environments.</p>
<h2 id="heading-metrics">Metrics</h2>
<p>Azure Monitor Metrics is a feature of Azure Monitor that collects numeric data from monitored resources into a time-series database. Metrics are numerical values that are collected at regular intervals and describe some aspect of a system at a particular time.</p>
<p>You can</p>
<ul>
<li><p>Visualize Data</p>
</li>
<li><p>Analyze</p>
</li>
<li><p>Alert</p>
</li>
<li><p>Automate</p>
</li>
</ul>
<h1 id="heading-health-checks">Health Checks</h1>
<p>Application Insights is an extension of Azure Monitor and provides application performance monitoring (APM) features. APM tools are useful to monitor applications from development, through test, and into production in the following ways:</p>
<ul>
<li><p>Proactively understand how an application is performing.</p>
</li>
<li><p>Reactively review application execution data to determine the cause of an incident.</p>
</li>
</ul>
<p>Application Insights helps us to create health checks.</p>
<h3 id="heading-availability-url-ping-test">Availability - URL Ping Test</h3>
<p>Send a HTTP Request to a specific URL</p>
<ul>
<li><p>Request duration and success rate</p>
</li>
<li><p>Dependent Requests</p>
</li>
<li><p>Enable retries are recommended</p>
</li>
<li><p>Min 5 Max 16 locations</p>
</li>
<li><p>Create alerts</p>
</li>
</ul>
<p>Monitor &gt; Application Insights &gt; Investigate &gt; Availability &gt; Add test</p>
<p>To notify =&gt; Create Action Group</p>
<p>In action group you can add SMS, Voice, Email, Push Notification and then create action.</p>
<p>Actions are</p>
<ul>
<li><p>Webhook</p>
</li>
<li><p>Azure Function</p>
</li>
<li><p>Runbook</p>
</li>
<li><p>Logic App</p>
</li>
<li><p>...</p>
</li>
</ul>
<h1 id="heading-load-and-failure-conditions">Load and Failure Conditions</h1>
<p>Plan for failures</p>
<p>Failure mode Analysis</p>
<ul>
<li><p>Find Single point of failure</p>
</li>
<li><p>Rate Risk and Severity</p>
</li>
<li><p>Determine Response</p>
</li>
<li><p>Understand Application</p>
</li>
<li><p>Criticality</p>
</li>
<li><p>Understand Dependencies</p>
</li>
</ul>
<p>Prevent Failures</p>
<ul>
<li><p>Fault Domains</p>
</li>
<li><p>Availability Zones</p>
</li>
<li><p>Cross-Regions</p>
</li>
<li><p>Auto Scaling</p>
</li>
</ul>
<p>Performance Testing</p>
<ul>
<li><p>Load Testing : Make sure that application handle normal load</p>
</li>
<li><p>Stress Testing : Analyze the upper limit of the application</p>
</li>
</ul>
<h1 id="heading-baseline-metrics">Baseline Metrics</h1>
<p>Normal condition is different for each environment</p>
<h1 id="heading-smart-detection-and-dynamic-thresholds">Smart Detection and Dynamic Thresholds</h1>
<p>Uses machine learning. Adopt new conditions.</p>
<p>It is built-in.</p>
<p>Failure needs a minimum 24 hours of data</p>
<p>Performance needs minimum 8 days of data</p>
<h1 id="heading-submodule">Submodule</h1>
<p>Submodules allow you to keep a Git repository as a subdirectory of another Git repository. This lets you clone another repository into your project and keep your commits separate.</p>
<pre><code class="lang-bash">git submodule init
git submodule update
git submodule add https://github.com/account/repo
</code></pre>
<h2 id="heading-azure-submodules">Azure Submodules</h2>
<p>Authentication should be either of below</p>
<ul>
<li><p>Unauthenticated</p>
</li>
<li><p>Authenticated with the main repo account</p>
</li>
</ul>
<h1 id="heading-scalar">Scalar</h1>
<p>Scalar is a repository management tool that optimizes Git for use in large repositories. Scalar improves performance by configuring advanced Git settings, maintaining repositories in the background, and helping to reduce data sent across the network.</p>
<p>New Repo:</p>
<pre><code class="lang-bash">scalar <span class="hljs-built_in">clone</span> [options] &lt;url&gt;
</code></pre>
<p>Existing Repo</p>
<pre><code class="lang-bash">scalar register
</code></pre>
<h1 id="heading-github-andamp-aad">Github &amp; AAD</h1>
<p>Requirements</p>
<ul>
<li>Github Enterprise Cloud Organization</li>
</ul>
<h1 id="heading-git-commands">Git Commands</h1>
<pre><code class="lang-bash">git <span class="hljs-built_in">log</span> --oneline
git <span class="hljs-built_in">log</span> --pretty=<span class="hljs-string">"- s%"</span>
</code></pre>
<h1 id="heading-branching-strategies">Branching Strategies</h1>
<ul>
<li><p>Trunk Based</p>
</li>
<li><p>Feature (Task) Based</p>
</li>
<li><p>Release Based</p>
</li>
</ul>
<h1 id="heading-pull-request">Pull Request</h1>
<p>Should contain</p>
<ul>
<li><p>What</p>
</li>
<li><p>Why</p>
</li>
<li><p>How</p>
</li>
<li><p>Test</p>
</li>
<li><p>References</p>
<ul>
<li><p>Work Item</p>
</li>
<li><p>Screenshot</p>
</li>
<li><p>Document</p>
</li>
</ul>
</li>
<li><p>The Rest</p>
<ul>
<li><p>Challenges</p>
</li>
<li><p>Improvements</p>
</li>
</ul>
</li>
</ul>
<p>Efficient Pull Request</p>
<ul>
<li><p>Automatically Assignment</p>
</li>
<li><p>Reminder</p>
</li>
<li><p>Pull Analytics</p>
</li>
</ul>
<p>Effective Code Review</p>
<ul>
<li><p>Size Limit</p>
<ul>
<li><p>Less than 400 lines of code</p>
</li>
<li><p>Less than one hour</p>
</li>
</ul>
</li>
<li><p>Annotation</p>
<ul>
<li><p>Guide reviewers</p>
</li>
<li><p>Provide Context</p>
</li>
</ul>
</li>
<li><p>Checklist</p>
</li>
</ul>
<h1 id="heading-static-code-analysis">Static Code Analysis</h1>
<ul>
<li><p>Coding Errors</p>
</li>
<li><p>Security Vulnerabilities</p>
</li>
</ul>
<p>GitHub Marketplace</p>
<ul>
<li><p>Code Quality</p>
</li>
<li><p>Code Review</p>
<ul>
<li>DeepSource</li>
</ul>
</li>
</ul>
<h1 id="heading-git-tags">Git Tags</h1>
<p>Mark specific versions in history</p>
<ul>
<li>Supports annotation</li>
</ul>
<p>Kinds</p>
<ul>
<li><p>Lightweight</p>
<ul>
<li><p>Just a tag</p>
</li>
<li><p>Simply point to a time in history</p>
</li>
</ul>
</li>
<li><p>Annotated</p>
<ul>
<li>Attached note on a tag</li>
</ul>
</li>
</ul>
<p>Web Portal: Only annotated</p>
<h1 id="heading-handling-large-files">Handling Large Files</h1>
<p>For large files, use Git LFS (Large File System)</p>
<ul>
<li><p>Open Source Extention installed separately</p>
</li>
<li><p>Large file is hosted seperataley</p>
</li>
</ul>
<pre><code class="lang-bash">git lfs install
git lfs track <span class="hljs-string">"*.psd"</span>
</code></pre>
<p>Tricks</p>
<ul>
<li><p>Do not commit produced binaries</p>
</li>
<li><p>Cleanup = git gc (Remove untracked files)</p>
</li>
</ul>
<h1 id="heading-remove-unwanted-data">Remove unwanted data</h1>
<ul>
<li>Need to remove secure data/file/secret/GPDR/sensitive data</li>
</ul>
<h2 id="heading-remove-local-data">Remove local data</h2>
<p>1 - Delete unwanted data<br />2 - git rm --cached &lt;filename&gt;<br />3 - git reset HEAD^<br />4- git commit --ammend -m "comment"</p>
<h2 id="heading-remove-remote-repository">Remove Remote Repository</h2>
<p>1 - Reset to last good commit before the file commit<br />git reset --hard #commitSHA</p>
<p>2 - git push --force</p>
<h2 id="heading-remove-from-history">Remove from History</h2>
<p>Not easy. Use 3rd party tools</p>
<ul>
<li><p>git filter-branch</p>
</li>
<li><p>git filter-repo</p>
</li>
<li><p>BFG Repo cleaner</p>
</li>
</ul>
<h1 id="heading-pipeline-matrix">Pipeline Matrix</h1>
<p>A build matrix is something that comes out of product-based companies: you have a single code base that you need to build across multiple permutations of operating systems, software versions, etc.</p>
<pre><code class="lang-bash">trigger:
- master

strategy:
  matrix:
    <span class="hljs-string">'Ubuntu 16.04'</span>:
      image: <span class="hljs-string">'ubuntu-16.04'</span>
      dotnetcore: <span class="hljs-string">'2.2.x'</span>
    <span class="hljs-string">'Ubuntu 18.04'</span>:
      image: <span class="hljs-string">'ubuntu-18.04'</span>
      dotnetcore: <span class="hljs-string">'3.1.x'</span>
    <span class="hljs-string">'MacOS X High Sierra'</span>:
      image: <span class="hljs-string">'macos-10.13'</span>
      dotnetcore: <span class="hljs-string">'2.2.x'</span>
    <span class="hljs-string">'MacOS X Mojave'</span>:
      image: <span class="hljs-string">'macos-10.14'</span>
      dotnetcore: <span class="hljs-string">'3.1.x'</span>
    <span class="hljs-string">'Windows Server 2016'</span>:
      image: <span class="hljs-string">'vs2017-win2016'</span>
      dotnetcore: <span class="hljs-string">'2.2.x'</span>
    <span class="hljs-string">'Windows Server 2019'</span>:
      image: <span class="hljs-string">'windows-2019'</span>
      dotnetcore: <span class="hljs-string">'3.1.x'</span>

pool:
  vmImage: $(image)

variables:
  solution: <span class="hljs-string">'**/*.sln'</span>
  buildPlatform: <span class="hljs-string">'Any CPU'</span>
  buildConfiguration: <span class="hljs-string">'Release'</span>

steps:
- task: UseDotNet@2
  inputs:
    packageType: <span class="hljs-string">'sdk'</span>
    version: $(dotnetcore)

- task: DotNetCoreCLI@2
  displayName: <span class="hljs-string">"Restore"</span>
  inputs:
    <span class="hljs-built_in">command</span>: <span class="hljs-string">'restore'</span>
    projects: <span class="hljs-string">'**/*.csproj'</span>
    feedsToUse: <span class="hljs-string">'select'</span>

- task: DotNetCoreCLI@2
  displayName: <span class="hljs-string">"Build"</span>
  inputs:
    <span class="hljs-built_in">command</span>: <span class="hljs-string">'build'</span>
    projects: <span class="hljs-string">'**/*.csproj'</span>

- task: DotNetCoreCLI@2
  displayName: <span class="hljs-string">"Unit Tests"</span>
  inputs:
    <span class="hljs-built_in">command</span>: <span class="hljs-string">'test'</span>
    projects: <span class="hljs-string">'**/tests/UnitTests/UnitTests.csproj'</span>

- task: DotNetCoreCLI@2
  displayName: <span class="hljs-string">"Publish Infrastructure"</span>
  inputs:
    <span class="hljs-built_in">command</span>: <span class="hljs-string">'publish'</span>
    publishWebProjects: <span class="hljs-literal">false</span>
    projects: <span class="hljs-string">'$(Build.SourcesDirectory)/src/Infrastructure/Infrastructure.csproj'</span>

- task: DotNetCoreCLI@2
  displayName: <span class="hljs-string">"Publish ApplicationCore"</span>
  inputs:
    <span class="hljs-built_in">command</span>: <span class="hljs-string">'publish'</span>
    publishWebProjects: <span class="hljs-literal">false</span>
    projects: <span class="hljs-string">'$(Build.SourcesDirectory)/src/ApplicationCore/ApplicationCore.csproj'</span>

- task: DotNetCoreCLI@2
  displayName: <span class="hljs-string">"Publish Web"</span>
  inputs:
    <span class="hljs-built_in">command</span>: <span class="hljs-string">'publish'</span>
    publishWebProjects: <span class="hljs-literal">true</span>

- task: CopyFiles@2
  inputs:
    SourceFolder: <span class="hljs-string">'$(Build.SourcesDirectory)'</span>
    Contents: |
      src\ApplicationCore\bin\Debug\netstandard2.1\ApplicationCore.dll
      src\Infrastructure\bin\Debug\netstandard2.1\Infrastructure.dll
      src\Web\bin\Debug\netcoreapp3.1\Web.dll
      src\Web\bin\Debug\netcoreapp3.1\Web.Views.dll
    TargetFolder: <span class="hljs-string">'$(Build.ArtifactStagingDirectory)'</span>

- task: PublishPipelineArtifact@1
  inputs:
    targetPath: <span class="hljs-string">'$(Build.ArtifactStagingDirectory)'</span>
    artifact: <span class="hljs-string">'$(image)'</span>
    publishLocation: <span class="hljs-string">'pipeline'</span>
</code></pre>
<h1 id="heading-azure-artifacts">Azure Artifacts</h1>
<p>Supports Maven, NPM, Nuget, Python</p>
<h1 id="heading-semantic-versioning">Semantic Versioning</h1>
<p>2.5.7-prerelease</p>
<p>{major}.{minor}.{patch}-{tag}</p>
<h1 id="heading-yaml-templates">YAML Templates</h1>
<p>template.yml</p>
<pre><code class="lang-bash">steps
 - npm install
 - npm <span class="hljs-built_in">test</span>
tasks
</code></pre>
<p>pipeline-yml (external repo)</p>
<pre><code class="lang-bash">pool:
 image: ubuntu-latest

resources:
  repositories:
    - repository: templates
    - <span class="hljs-built_in">type</span>: git
    - name: project/repo

steps:
 - templates/template.yml@templates
</code></pre>
<p>pipeline-yml (same repo)</p>
<pre><code class="lang-bash">pool:
 image: ubuntu-latest

steps:
 - template.yml
</code></pre>
<h1 id="heading-variable-groups">Variable Groups</h1>
<p>Variable is only used once</p>
<pre><code class="lang-bash">variables:
 vmImageName: <span class="hljs-string">'ubuntu-latest'</span>

pool:
 vmImage: $(vmImageName)
</code></pre>
<p>Variable groups are used in multiple places (temples)</p>
<p>Pipeline &gt; Library</p>
<p>You can insert variable groups in pipelines. E.g. Secrets,...</p>
<pre><code class="lang-bash">variables:
 - group: my-variable-group
 - name: azureServiceConnectionId
   value: <span class="hljs-string">'{SUBSCRIPTION_ID}'</span>
</code></pre>
<h1 id="heading-powershell-dsc-desired-state-condiguration">Powershell DSC (Desired State Condiguration)</h1>
<p>Maintain state</p>
<pre><code class="lang-powershell">Configuration HelloWorld {

    <span class="hljs-comment"># Import the module that contains the File resource.</span>
    <span class="hljs-built_in">Import-DscResource</span> <span class="hljs-literal">-ModuleName</span> PsDesiredStateConfiguration

    <span class="hljs-comment"># The Node statement specifies which targets to compile MOF files for, when this configuration is executed.</span>
    Node <span class="hljs-string">'localhost'</span> {

        <span class="hljs-comment"># The File resource can ensure the state of files, or copy them from a source to a destination with persistent updates.</span>
        File HelloWorld {
            DestinationPath = <span class="hljs-string">"C:\Temp\HelloWorld.txt"</span>
            Ensure = <span class="hljs-string">"Present"</span>
            Contents   = <span class="hljs-string">"Hello World from DSC!"</span>
        }
    }
}
</code></pre>
<p><a target="_blank" href="https://www.techtarget.com/searchwindowsserver/definition/Microsoft-Windows-PowerShell-DSC-Desired-State-Configuration">https://www.techtarget.com/searchwindowsserver/definition/Microsoft-Windows-PowerShell-DSC-Desired-State-Configuration</a></p>
<h1 id="heading-bicep-files">Bicep Files</h1>
<p>Alternative to ARM templates</p>
<p>Abstraction over ARM templates.</p>
<p><a target="_blank" href="https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/overview?tabs=bicep">https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/overview?tabs=bicep</a></p>
<h1 id="heading-visual-studio-app-center">Visual Studio App Center</h1>
<p>Deploy application to multiple devices (IOS, Mac, Windows)</p>
<h1 id="heading-azure-ad-privileged-identity-management">Azure AD Privileged Identity Management</h1>
<p>Privileged Identity Management (PIM) is a service in Azure Active Directory (Azure AD) that enables you to manage, control, and monitor access to important resources in your organization. These resources include resources in Azure AD, Azure, and other Microsoft Online Services such as Microsoft 365 or Microsoft Intune. The following video explains important PIM concepts and features.</p>
<p>What does it do?</p>
<p>Privileged Identity Management provides time-based and approval-based role activation to mitigate the risks of excessive, unnecessary, or misused access permissions on resources that you care about. Here are some of the key features of Privileged Identity Management:</p>
<ul>
<li><p>Provide <strong>just-in-time</strong> privileged access to Azure AD and Azure resources</p>
</li>
<li><p>Assign <strong>time-bound</strong> access to resources using start and end dates</p>
</li>
<li><p>Require <strong>approval</strong> to activate privileged roles</p>
</li>
<li><p>Enforce <strong>multi-factor authentication</strong> to activate any role</p>
</li>
<li><p>Use <strong>justification</strong> to understand why users activate</p>
</li>
<li><p>Get <strong>notifications</strong> when privileged roles are activated</p>
</li>
<li><p>Conduct <strong>access reviews</strong> to ensure users still need roles</p>
</li>
<li><p>Download <strong>audit history</strong> for internal or external audit</p>
</li>
<li><p>Prevents removal of the <strong>last active Global Administrator</strong> and <strong>Privileged Role Administrator</strong> role assignments</p>
</li>
</ul>
<h1 id="heading-azure-ad-conditional-access">Azure AD Conditional Access</h1>
<p>if then statements for actions</p>
<ul>
<li><p>Scope</p>
</li>
<li><p>Condition</p>
</li>
<li><p>Make Condition</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Exploring Output Cache]]></title><description><![CDATA[Introduction
Output Caching was one of my favorite features in .Net Framework. Unfortunately, output caching was not available .Net Core until .Net 7 version.
The output caching middleware enables caching of HTTP responses. .Net saves the cached entr...]]></description><link>https://dotdev.com.tr/exploring-output-cache</link><guid isPermaLink="true">https://dotdev.com.tr/exploring-output-cache</guid><category><![CDATA[C#]]></category><category><![CDATA[.NET]]></category><dc:creator><![CDATA[İbrahim Uludağ]]></dc:creator><pubDate>Tue, 17 Jan 2023 11:22:18 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/-8_Se9Ll5NY/upload/f99f5de04447640bed079351a448cdf2.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-introduction">Introduction</h1>
<p><em>Output Caching</em> was one of my favorite features in .Net Framework. Unfortunately, output caching was not available <em>.Net Core</em> until .Net 7 version.</p>
<p>The output caching middleware enables caching of HTTP responses. .Net saves the cached entries on the server. Thus, you have more control over caching.</p>
<p>The output caching middleware can be used in all types of <a target="_blank" href="http://ASP.NET">ASP.NET</a> Core apps: Minimal API, Web API with controllers, MVC, and Razor Pages.</p>
<h1 id="heading-basics">Basics</h1>
<p>Add output cache middleware to services and then to the processing pipeline as below.</p>
<pre><code class="lang-csharp">builder.Services.AddOutputCache();
.....
app.UseOutputCache();
</code></pre>
<p>Add <code>[OutputCache]</code> attribute to your controller.</p>
<pre><code class="lang-csharp">[<span class="hljs-meta">HttpGet(Name = <span class="hljs-meta-string">"GetWeatherForecast Default"</span>)</span>]
[<span class="hljs-meta">OutputCache</span>]
<span class="hljs-function"><span class="hljs-keyword">public</span> IEnumerable&lt;WeatherForecast&gt; <span class="hljs-title">GetDefault</span>(<span class="hljs-params"></span>)</span>
{
....
}
</code></pre>
<p>For a <code>minimal API</code>, you can configure it as below.</p>
<pre><code class="lang-csharp">app.MapGet(<span class="hljs-string">"/cached"</span>, Gravatar.WriteGravatar).CacheOutput();
app.MapGet(<span class="hljs-string">"/attribute"</span>, [OutputCache] (context) =&gt; 
   Gravatar.WriteGravatar(context));
</code></pre>
<p>As you can see, it is very easy to add output caching. The next step is configuration.</p>
<h1 id="heading-configuration">Configuration</h1>
<p>There are simply two places for configuring the output cache.</p>
<ul>
<li><p><code>AddOutputCache</code></p>
</li>
<li><p><code>OutputCacheAttribute</code></p>
</li>
</ul>
<h2 id="heading-addoutputcache">AddOutputCache</h2>
<p>Add your policies while calling <code>AddOutputCache</code>.</p>
<pre><code class="lang-csharp">builder.Services.AddOutputCache(options =&gt;
    {
        options.AddBasePolicy(builder =&gt;
            builder.Expire(TimeSpan.FromSeconds(<span class="hljs-number">10</span>)));

        options.AddPolicy(<span class="hljs-string">"Expire20"</span>, builder =&gt;
            builder.Expire(TimeSpan.FromSeconds(<span class="hljs-number">20</span>)));

        options.AddPolicy(<span class="hljs-string">"Expire30"</span>, builder =&gt;
            builder.Expire(TimeSpan.FromSeconds(<span class="hljs-number">30</span>)));    
    });
</code></pre>
<p><code>AddBasePolicy</code> is the default policy. If nothing is specified, this policy will be used. <code>builder.Expire(TimeSpan.FromSeconds(10)</code> specifies when the cached entry will expire.</p>
<p>For <code>Controllers</code>, you can specify your policy in the attribute.</p>
<pre><code class="lang-csharp">[<span class="hljs-meta">HttpGet(<span class="hljs-meta-string">"get-bypolicy"</span>, Name = <span class="hljs-meta-string">"GetWeatherForecast Policy"</span>)</span>]
[<span class="hljs-meta">OutputCache(PolicyName = <span class="hljs-meta-string">"Expire20"</span>)</span>]
<span class="hljs-function"><span class="hljs-keyword">public</span> IEnumerable&lt;WeatherForecast&gt; <span class="hljs-title">GetPolicy</span>(<span class="hljs-params"></span>)</span>
{
....
}
</code></pre>
<p>For a <code>minimal API</code>, you can use as below.</p>
<pre><code class="lang-csharp">app.MapGet(<span class="hljs-string">"/20"</span>, Gravatar.WriteGravatar).CacheOutput(<span class="hljs-string">"Expire20"</span>);
app.MapGet(<span class="hljs-string">"/30"</span>, [OutputCache(PolicyName = <span class="hljs-string">"Expire30"</span>)] (context) =&gt; 
    Gravatar.WriteGravatar(context));
</code></pre>
<h1 id="heading-cache-key">Cache Key</h1>
<ul>
<li><p><a target="_blank" href="https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.outputcaching.outputcachepolicybuilder.setvarybyquery">SetVaryByQuery</a> - Specify one or more query string names to add to the cache key.</p>
</li>
<li><p><a target="_blank" href="https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.outputcaching.outputcachepolicybuilder.setvarybyheader">SetVaryByHeader</a> - Specify one or more HTTP headers to add to the cache key.</p>
</li>
<li><p><a target="_blank" href="https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.outputcaching.outputcachepolicybuilder.varybyvalue">VaryByValue</a>- Specify a value to add to the cache key. The following example uses a value that indicates whether the current server time in seconds is odd or even. A new response is generated only when the number of seconds goes from odd to even or even to odd.</p>
</li>
</ul>
<p>For example, you want the cache temperatures by city. You can achieve this by using <code>SetVaryByQuery</code>. You can specify this in either <code>AddOutputCache</code> or <code>OutputCache</code> attribute.</p>
<pre><code class="lang-csharp">[<span class="hljs-meta">HttpGet(<span class="hljs-meta-string">"{city}"</span>, Name = <span class="hljs-meta-string">"GetWeatherForecast Query"</span>)</span>]
[<span class="hljs-meta">OutputCache(VaryByQueryKeys = new[</span>] { <span class="hljs-string">"city"</span> })]
<span class="hljs-function"><span class="hljs-keyword">public</span> IEnumerable&lt;WeatherForecast&gt; <span class="hljs-title">GetByQuery</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> city</span>)</span>
{
...
}
</code></pre>
<h1 id="heading-what-can-you-cache">What can you cache?</h1>
<p>By default, output caching follows these rules:</p>
<ul>
<li><p>Only HTTP 200 responses are cached.</p>
</li>
<li><p>Only HTTP GET or HEAD requests are cached.</p>
</li>
<li><p>Responses that set cookies aren't cached.</p>
</li>
<li><p>Responses to authenticated requests aren't cached.</p>
</li>
</ul>
<h1 id="heading-conclusion">Conclusion</h1>
<p>Output caching is a very simple and powerful feature of .Net 7. With a little effort, you can improve the performance of your applications.</p>
<h1 id="heading-references">References</h1>
<ul>
<li><p><a target="_blank" href="https://learn.microsoft.com/en-us/aspnet/core/performance/caching/output?view=aspnetcore-7.0">https://learn.microsoft.com/en-us/aspnet/core/performance/caching/output?view=aspnetcore-7.0</a></p>
</li>
<li><p><a target="_blank" href="https://learn.microsoft.com/en-us/aspnet/core/performance/caching/overview?view=aspnetcore-7.0">https://learn.microsoft.com/en-us/aspnet/core/performance/caching/overview?view=aspnetcore-7.0</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[7 New Features of C# 11]]></title><description><![CDATA[Microsoft released C# 11 on November 2022. C# 11 has great new features and enhancements. You will like these features, especially Required Member and Raw String Literals.
You can find the source code for this post on my GitHub repository.
Let's disc...]]></description><link>https://dotdev.com.tr/7-new-features-of-c-11</link><guid isPermaLink="true">https://dotdev.com.tr/7-new-features-of-c-11</guid><category><![CDATA[C#]]></category><dc:creator><![CDATA[İbrahim Uludağ]]></dc:creator><pubDate>Sun, 15 Jan 2023 20:25:39 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/cckf4TsHAuw/upload/af68d68f4ac642d777fe9ab4d10d4ece.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Microsoft released C# 11 on November 2022. C# 11 has great new features and enhancements. You will like these features, especially <em>Required Member</em> and <em>Raw String Literals.</em></p>
<p>You can find the source code for this post on my <a target="_blank" href="https://github.com/ibrahimuludag/CSharp11">GitHub repository</a>.</p>
<p>Let's discover C# 11.</p>
<h1 id="heading-1-raw-string-literals">1 - Raw String Literals</h1>
<p>I have been waiting for this feature for a long time. No more escaping strings.</p>
<p>You can create multiline strings as below.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">string</span> rawStringLiteralDelimiter = <span class="hljs-string">""</span><span class="hljs-string">""</span>
    Raw <span class="hljs-keyword">string</span> literals are delimited 
    <span class="hljs-keyword">by</span> a <span class="hljs-keyword">string</span> of at least three <span class="hljs-keyword">double</span> quotes,
    like <span class="hljs-keyword">this</span>: <span class="hljs-string">""</span><span class="hljs-string">"
    "</span><span class="hljs-string">""</span><span class="hljs-string">";</span>
</code></pre>
<p>A raw string literal starts with at least three double-quote (""") characters. It ends with the same number of double-quote characters. Typically, a raw string literal uses three double quotes on a single line to start the string, and three double quotes on a separate line to end the string.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">string</span> singleLine = <span class="hljs-string">""</span><span class="hljs-string">"Friends say "</span>hello<span class="hljs-string">" as they pass by."</span><span class="hljs-string">""</span>;
</code></pre>
<p>Embedding XML and JSON string is a piece of cake now.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">string</span> embeddedXML = <span class="hljs-string">""</span><span class="hljs-string">"
       &lt;element attr = "</span>content<span class="hljs-string">"&gt;
           &lt;body style="</span>normal<span class="hljs-string">"&gt;
               Here is the main text
           &lt;/body&gt;
           &lt;footer&gt;
               Excerpts from "</span>An amazing story<span class="hljs-string">"
           &lt;/footer&gt;
       &lt;/element &gt;
       "</span><span class="hljs-string">""</span>;

<span class="hljs-keyword">string</span> jsonString = <span class="hljs-string">""</span><span class="hljs-string">"
{
  "</span>Date<span class="hljs-string">": "</span><span class="hljs-number">2019</span><span class="hljs-number">-08</span><span class="hljs-number">-01</span>T00:<span class="hljs-number">00</span>:<span class="hljs-number">00</span><span class="hljs-number">-07</span>:<span class="hljs-number">00</span><span class="hljs-string">",
  "</span>TemperatureCelsius<span class="hljs-string">": 25,
  "</span>Summary<span class="hljs-string">": "</span>Hot<span class="hljs-string">",
  "</span>DatesAvailable<span class="hljs-string">": [
    "</span><span class="hljs-number">2019</span><span class="hljs-number">-08</span><span class="hljs-number">-01</span>T00:<span class="hljs-number">00</span>:<span class="hljs-number">00</span><span class="hljs-number">-07</span>:<span class="hljs-number">00</span><span class="hljs-string">",
    "</span><span class="hljs-number">2019</span><span class="hljs-number">-08</span><span class="hljs-number">-02</span>T00:<span class="hljs-number">00</span>:<span class="hljs-number">00</span><span class="hljs-number">-07</span>:<span class="hljs-number">00</span><span class="hljs-string">"
  ],
  "</span>TemperatureRanges<span class="hljs-string">": {
    "</span>Cold<span class="hljs-string">": {
      "</span>High<span class="hljs-string">": 20,
      "</span>Low<span class="hljs-string">": -10
    },
    "</span>Hot<span class="hljs-string">": {
      "</span>High<span class="hljs-string">": 60,
      "</span>Low<span class="hljs-string">": 20
    }
            },
  "</span>SummaryWords<span class="hljs-string">": [
    "</span>Cool<span class="hljs-string">",
    "</span>Windy<span class="hljs-string">",
    "</span>Humid<span class="hljs-string">"
  ]
}
"</span><span class="hljs-string">""</span>;
</code></pre>
<p>The following examples demonstrate the compiler errors reported based on these rules:</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// CS8997: Unterminated raw string literal.</span>
<span class="hljs-keyword">var</span> multiLineStart = <span class="hljs-string">""</span><span class="hljs-string">"This
    is the beginning of a string 
    "</span><span class="hljs-string">""</span>;

<span class="hljs-comment">// CS9000: Raw string literal delimiter must be on its own line.</span>
<span class="hljs-keyword">var</span> multiLineEnd = <span class="hljs-string">""</span><span class="hljs-string">"
    This is the beginning of a string "</span><span class="hljs-string">""</span>;

<span class="hljs-comment">// CS8999: Line does not start with the same whitespace as the closing line</span>
<span class="hljs-comment">// of the raw string literal</span>
<span class="hljs-keyword">var</span> noOutdenting = <span class="hljs-string">""</span><span class="hljs-string">"
    A line of text.
Trying to outdent the second line.
    "</span><span class="hljs-string">""</span>;
</code></pre>
<h1 id="heading-2-required-members">2 - Required Members</h1>
<p>You can add the <strong>required</strong> modifier to properties and fields to enforce constructors and callers to initialize those values.</p>
<p>Previously, I was using constructors to ensure obligatory properties were set. However, this method increased the complexity and maintainability of my code. Now, with the help of the <strong>required</strong> modifier, this is easier.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Book</span>
{
    <span class="hljs-keyword">public</span> required <span class="hljs-keyword">string</span> Title { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
    <span class="hljs-keyword">public</span> required <span class="hljs-keyword">string</span> Author { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span>? Pages { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
}

<span class="hljs-comment">// This will compile</span>
<span class="hljs-keyword">var</span> solito = <span class="hljs-keyword">new</span> Book { Author = <span class="hljs-string">"Javier Zamora"</span>, Title = <span class="hljs-string">"Solito: A Memoir"</span> };

<span class="hljs-comment">// This will not compile</span>
<span class="hljs-keyword">var</span> solitoError = <span class="hljs-keyword">new</span> Book { Author = <span class="hljs-string">"Javier Zamora"</span> };
</code></pre>
<p>You will also see the <strong>required</strong> properties on IntelliSense.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1673812798263/c8a76c0d-dcaf-44a6-b08e-6c04e0b1136a.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-3-auto-default-structs">3 - Auto Default Structs</h1>
<p>The C# 11 compiler ensures that all fields of a <strong>struct</strong> type are initialized to their default value as part of executing a constructor.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">struct</span> Coordinate
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> Longitude { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> Latitude { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">string</span> <span class="hljs-title">ToString</span>(<span class="hljs-params"></span>)</span>
    {
        <span class="hljs-keyword">return</span> <span class="hljs-string">$"Longitude : <span class="hljs-subst">{Longitude}</span>, Latitude : <span class="hljs-subst">{Latitude}</span>"</span>;
    }
}

Console.WriteLine(<span class="hljs-keyword">new</span> Coordinate());

<span class="hljs-comment">// Output is as below</span>
<span class="hljs-comment">// Longitude : 0, Latitude : 0</span>
</code></pre>
<h1 id="heading-4-file-local-type">4 - File Local Type</h1>
<p>Beginning in C# 11, you can use the <strong>file</strong> access modifier to create a type whose visibility is scoped to the source file in which it is declared. This feature helps source generator authors avoid naming collisions.</p>
<h1 id="heading-5-generic-attributes">5 - Generic Attributes</h1>
<p>You can declare a generic class whose base class is System.Attribute. This feature provides a more convenient syntax for attributes that require a System.Type parameter.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">GenericAttribute</span>&lt;<span class="hljs-title">T</span>&gt; : <span class="hljs-title">Attribute</span> {
    <span class="hljs-keyword">public</span> T Name { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">private</span> <span class="hljs-keyword">set</span>; }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">GenericAttribute</span>(<span class="hljs-params">T name</span>)</span>
    {
        Name = name;
    }
}

[<span class="hljs-meta">Generic&lt;int&gt;(10)</span>]
<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">GenericClass1</span>
{
}

[<span class="hljs-meta">Generic&lt;string&gt;(<span class="hljs-meta-string">"Hello World"</span>)</span>]
<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">GenericClass2</span>
{
}


<span class="hljs-comment">// Below will not compile</span>
[<span class="hljs-meta">Generic&lt;T&gt;()</span>]
<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">GenericClass3</span>&lt;<span class="hljs-title">T</span>&gt;
{
}
</code></pre>
<h1 id="heading-6-list-patterns">6 - List Patterns</h1>
<p>In previous versions of C#, pattern matching was introduced. In C#11 pattern matching was extended to use lists and arrays.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">int</span>[] numbers = { <span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span> };

Console.WriteLine(numbers <span class="hljs-keyword">is</span> [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]);  <span class="hljs-comment">// True</span>
Console.WriteLine(numbers <span class="hljs-keyword">is</span> [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">4</span>]);  <span class="hljs-comment">// False</span>
Console.WriteLine(numbers <span class="hljs-keyword">is</span> [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>]);  <span class="hljs-comment">// False</span>
Console.WriteLine(numbers <span class="hljs-keyword">is</span> [<span class="hljs-number">0</span> or <span class="hljs-number">1</span>, &lt;= <span class="hljs-number">2</span>, &gt;= <span class="hljs-number">3</span>]);  <span class="hljs-comment">// True</span>

<span class="hljs-comment">// Discard pattern "_"</span>
<span class="hljs-comment">// Slice pattern ".."</span>
Console.WriteLine(<span class="hljs-keyword">new</span>[] { <span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span> } <span class="hljs-keyword">is</span> [&gt; <span class="hljs-number">0</span>, &gt; <span class="hljs-number">0</span>, ..]);  <span class="hljs-comment">// True</span>
Console.WriteLine(<span class="hljs-keyword">new</span>[] { <span class="hljs-number">1</span>, <span class="hljs-number">1</span> } <span class="hljs-keyword">is</span> [_, _, ..]);  <span class="hljs-comment">// True</span>
Console.WriteLine(<span class="hljs-keyword">new</span>[] { <span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span> } <span class="hljs-keyword">is</span> [&gt; <span class="hljs-number">0</span>, &gt; <span class="hljs-number">0</span>, ..]);  <span class="hljs-comment">// False</span>
Console.WriteLine(<span class="hljs-keyword">new</span>[] { <span class="hljs-number">1</span> } <span class="hljs-keyword">is</span> [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, ..]);  <span class="hljs-comment">// False</span>

Console.WriteLine(<span class="hljs-keyword">new</span>[] { <span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span> } <span class="hljs-keyword">is</span> [.., &gt; <span class="hljs-number">0</span>, &gt; <span class="hljs-number">0</span>]);  <span class="hljs-comment">// True</span>
Console.WriteLine(<span class="hljs-keyword">new</span>[] { <span class="hljs-number">2</span>, <span class="hljs-number">4</span> } <span class="hljs-keyword">is</span> [.., &gt; <span class="hljs-number">0</span>, <span class="hljs-number">2</span>, <span class="hljs-number">4</span>]);  <span class="hljs-comment">// False</span>
Console.WriteLine(<span class="hljs-keyword">new</span>[] { <span class="hljs-number">2</span>, <span class="hljs-number">4</span> } <span class="hljs-keyword">is</span> [.., <span class="hljs-number">2</span>, <span class="hljs-number">4</span>]);  <span class="hljs-comment">// True</span>

Console.WriteLine(<span class="hljs-keyword">new</span>[] { <span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span> } <span class="hljs-keyword">is</span> [&gt;= <span class="hljs-number">0</span>, .., <span class="hljs-number">2</span> or <span class="hljs-number">4</span>]);  <span class="hljs-comment">// True</span>
Console.WriteLine(<span class="hljs-keyword">new</span>[] { <span class="hljs-number">1</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">1</span> } <span class="hljs-keyword">is</span> [<span class="hljs-number">1</span>, <span class="hljs-number">0</span>, .., <span class="hljs-number">0</span>, <span class="hljs-number">1</span>]);  <span class="hljs-comment">// True</span>
Console.WriteLine(<span class="hljs-keyword">new</span>[] { <span class="hljs-number">1</span>, <span class="hljs-number">0</span>, <span class="hljs-number">1</span> } <span class="hljs-keyword">is</span> [<span class="hljs-number">1</span>, <span class="hljs-number">0</span>, .., <span class="hljs-number">0</span>, <span class="hljs-number">1</span>]);  <span class="hljs-comment">// False</span>
</code></pre>
<h1 id="heading-7-utf8-string-literals">7 - Utf8 String Literals</h1>
<p>You can specify the <strong>u8</strong> suffix on a string literal to specify UTF-8 character encoding. If your application needs UTF-8 strings for HTTP string constants or similar text protocols, you can use this feature to simplify the creation of UTF-8 strings.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">string</span> s1 = <span class="hljs-string">"hello"</span>u8;             <span class="hljs-comment">// Error</span>
<span class="hljs-keyword">var</span> s2 = <span class="hljs-string">"hello"</span>u8;                <span class="hljs-comment">// Okay and type is ReadOnlySpan&lt;byte&gt;</span>
ReadOnlySpan&lt;<span class="hljs-keyword">byte</span>&gt; s3 = <span class="hljs-string">"hello"</span>u8; <span class="hljs-comment">// Okay.</span>
<span class="hljs-keyword">byte</span>[] s4 = <span class="hljs-string">"hello"</span>u8;             <span class="hljs-comment">// Error - Cannot implicitly convert type 'System.ReadOnlySpan&lt;byte&gt;' to 'byte[]'.</span>
<span class="hljs-keyword">byte</span>[] s5 = <span class="hljs-string">"hello"</span>u8.ToArray();   <span class="hljs-comment">// Okay.</span>
Span&lt;<span class="hljs-keyword">byte</span>&gt; s6 = <span class="hljs-string">"hello"</span>u8;         <span class="hljs-comment">// Error - Cannot implicitly convert type 'System.ReadOnlySpan&lt;byte&gt;' to 'System.Span&lt;byte&gt;'.</span>
</code></pre>
<h1 id="heading-conclusion">Conclusion</h1>
<p>These are several features of C# 11. If you want to learn more, you can go to <a target="_blank" href="https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-11">"What's new in C# 11"</a>.</p>
<p>Happy Coding!</p>
<h1 id="heading-references">References</h1>
<ul>
<li><p><a target="_blank" href="https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-11">https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-11</a></p>
</li>
<li><p><a target="_blank" href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/struct#struct-initialization-and-default-values">https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/struct#struct-initialization-and-default-values</a></p>
</li>
<li><p><a target="_blank" href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/file">https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/file</a></p>
</li>
<li><p><a target="_blank" href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/patterns">https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/patterns</a></p>
</li>
<li><p><a target="_blank" href="https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/strings">https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/strings</a></p>
</li>
<li><p><a target="_blank" href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-11.0/utf8-string-literals">https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-11.0/utf8-string-literals</a></p>
</li>
</ul>
]]></content:encoded></item></channel></rss>