<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rupinder Kaur</title>
    <description>The latest articles on DEV Community by Rupinder Kaur (@rupinder_kaur_6730d267d5f).</description>
    <link>https://dev.to/rupinder_kaur_6730d267d5f</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3277047%2F4744c440-6bb5-4e59-9ad3-291d2a566556.jpg</url>
      <title>DEV Community: Rupinder Kaur</title>
      <link>https://dev.to/rupinder_kaur_6730d267d5f</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rupinder_kaur_6730d267d5f"/>
    <language>en</language>
    <item>
      <title>How to Use Code Metrics in .NET to Refactor Complex API Controllers</title>
      <dc:creator>Rupinder Kaur</dc:creator>
      <pubDate>Thu, 05 Feb 2026 03:37:38 +0000</pubDate>
      <link>https://dev.to/rupinder_kaur_6730d267d5f/how-to-use-code-metrics-in-net-to-refactor-complex-api-controllers-lle</link>
      <guid>https://dev.to/rupinder_kaur_6730d267d5f/how-to-use-code-metrics-in-net-to-refactor-complex-api-controllers-lle</guid>
      <description>&lt;p&gt;Have you ever opened an API controller and thought, “Whoa, this looks like spaghetti”? 😵‍💫 If you’re working with legacy .NET projects or scaling up a growing codebase, complexity can creep in quickly. That’s where &lt;strong&gt;Visual Studio’s Code Metrics&lt;/strong&gt; come to the rescue.&lt;/p&gt;

&lt;p&gt;In this post, I’ll walk you through:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What each code metric means
&lt;/li&gt;
&lt;li&gt;How to use them to identify messy code
&lt;/li&gt;
&lt;li&gt;A real-life example of refactoring a bloated API controller
&lt;/li&gt;
&lt;li&gt;A checklist to guide your review process&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s dive in! 🧩&lt;/p&gt;




&lt;h2&gt;
  
  
  🔍 What Are Code Metrics?
&lt;/h2&gt;

&lt;p&gt;Code metrics help quantify how maintainable, complex, and testable your code is. Visual Studio provides these metrics via:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Analyze → Analyze Code Metrics
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🖼️ &lt;em&gt;Image: Visual Studio Code Metrics Panel&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;A screenshot of Visual Studio’s Code Metrics results showing Maintainability Index, Cyclomatic Complexity, etc.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  📊 Code Metrics Explained
&lt;/h2&gt;

&lt;p&gt;Here’s what each metric means and why it matters:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Maintainability Index (MI)&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Definition&lt;/strong&gt;: A numeric score (0–100) indicating how easy it is to maintain a code element.&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;80–100&lt;/strong&gt;: Easy to maintain
&lt;/li&gt;
&lt;li&gt;⚠️ &lt;strong&gt;50–79&lt;/strong&gt;: Moderate
&lt;/li&gt;
&lt;li&gt;❌ &lt;strong&gt;0–49&lt;/strong&gt;: Hard to maintain&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;Cyclomatic Complexity (CC)&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Definition&lt;/strong&gt;: The number of independent paths through the code. Increases with &lt;code&gt;if&lt;/code&gt;, &lt;code&gt;switch&lt;/code&gt;, &lt;code&gt;for&lt;/code&gt;, etc.&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;&amp;lt;10&lt;/strong&gt;: Simple
&lt;/li&gt;
&lt;li&gt;⚠️ &lt;strong&gt;10–20&lt;/strong&gt;: Moderate
&lt;/li&gt;
&lt;li&gt;❌ &lt;strong&gt;&amp;gt;20&lt;/strong&gt;: Complex&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. &lt;strong&gt;Depth of Inheritance&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Definition&lt;/strong&gt;: The number of class levels above the current class in the hierarchy.&lt;/li&gt;
&lt;li&gt;✅ 0–3: Ideal
&lt;/li&gt;
&lt;li&gt;❌ &amp;gt;4: May be problematic&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. &lt;strong&gt;Class Coupling&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Definition&lt;/strong&gt;: Number of external classes/types referenced.&lt;/li&gt;
&lt;li&gt;✅ &amp;lt;10: Low coupling (preferred)
&lt;/li&gt;
&lt;li&gt;❌ &amp;gt;20: High coupling (bad for maintainability)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. &lt;strong&gt;Lines of Executable Code&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Definition&lt;/strong&gt;: Number of actual executable lines of code (ignores comments/braces).&lt;/li&gt;
&lt;li&gt;✅ &amp;lt;200 per class, &amp;lt;50 per method
&lt;/li&gt;
&lt;li&gt;❌ &amp;gt;500: Too complex, consider breaking apart&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🖼️ &lt;em&gt;Image: Metric Definitions Heatmap Table&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;A visual summary showing good, warning, and bad ranges for each metric (green-yellow-red).&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ Code Metrics Review Checklist
&lt;/h2&gt;

&lt;p&gt;Here’s a handy checklist to evaluate your API controllers or classes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] &lt;strong&gt;MI &amp;lt; 50?&lt;/strong&gt; Refactor needed!&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;CC &amp;gt; 10?&lt;/strong&gt; Simplify or extract methods.&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;Inheritance depth &amp;gt; 3?&lt;/strong&gt; Consider flattening it.&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;Class coupling &amp;gt; 10?&lt;/strong&gt; Break dependencies, inject interfaces.&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;Too many LOC?&lt;/strong&gt; Break into smaller classes/services.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧪 Real-Life Example: Refactoring a Bloated API Controller
&lt;/h2&gt;

&lt;p&gt;Let’s say you have this &lt;code&gt;OrdersController&lt;/code&gt;. Everything works, but the code smells.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrdersController&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ControllerBase&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HttpPost&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IActionResult&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;CreateOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OrderDto&lt;/span&gt; &lt;span class="n"&gt;dto&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dto&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;dto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;BadRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid order"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Customers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FindAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CustomerId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;NotFound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Customer not found"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Order&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;CustomerId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CustomerId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;CreatedAt&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UtcNow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Items&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;OrderItem&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;ProductId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ProductId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;Quantity&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Quantity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;Price&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Price&lt;/span&gt;
            &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;ToList&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveChangesAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Order &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; created"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🖼️ &lt;em&gt;Image: OrdersController Before Refactor&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Highlight that business logic, DB operations, and validation are all mixed in the controller.&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  ⚠️ Code Metrics Report
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;Issue&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Maintainability Index&lt;/td&gt;
&lt;td&gt;47 ❌&lt;/td&gt;
&lt;td&gt;Too low&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cyclomatic Complexity&lt;/td&gt;
&lt;td&gt;15 ⚠️&lt;/td&gt;
&lt;td&gt;Too many branches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Class Coupling&lt;/td&gt;
&lt;td&gt;12 ⚠️&lt;/td&gt;
&lt;td&gt;High dependencies&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Executable LOC&lt;/td&gt;
&lt;td&gt;80 ⚠️&lt;/td&gt;
&lt;td&gt;Too much logic in one method&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h3&gt;
  
  
  🔧 Refactoring Plan
&lt;/h3&gt;

&lt;p&gt;We move logic to a new &lt;code&gt;OrderService&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderService&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IOrderService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;CreateOrderAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OrderDto&lt;/span&gt; &lt;span class="n"&gt;dto&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Customers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FindAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CustomerId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                      &lt;span class="p"&gt;??&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Customer not found"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Order&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;CustomerId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CustomerId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;CreatedAt&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UtcNow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Items&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;OrderItem&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;ProductId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ProductId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;Quantity&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Quantity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;Price&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Price&lt;/span&gt;
            &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;ToList&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveChangesAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Order &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; created"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Updated controller:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HttpPost&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IActionResult&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;CreateOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OrderDto&lt;/span&gt; &lt;span class="n"&gt;dto&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;orderId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_orderService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateOrderAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dto&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orderId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Error creating order"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;BadRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🖼️ &lt;em&gt;Image: Refactored Architecture Diagram&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Show controller → service → dbContext pattern (clean layering).&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  🎯 After Refactoring Metrics
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;Improvement&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Maintainability Index&lt;/td&gt;
&lt;td&gt;90 ✅&lt;/td&gt;
&lt;td&gt;Big boost&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cyclomatic Complexity&lt;/td&gt;
&lt;td&gt;3 ✅&lt;/td&gt;
&lt;td&gt;Clean logic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Class Coupling&lt;/td&gt;
&lt;td&gt;4 ✅&lt;/td&gt;
&lt;td&gt;Reduced&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Executable LOC&lt;/td&gt;
&lt;td&gt;20 ✅&lt;/td&gt;
&lt;td&gt;Much leaner&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  🖼️ &lt;em&gt;Image: Before vs After Metrics Bar Chart&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Visual comparison of metric values before and after refactoring.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 Lessons Learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Metrics are &lt;strong&gt;not just numbers&lt;/strong&gt;—they’re clues to identify code smells.
&lt;/li&gt;
&lt;li&gt;Refactoring based on metrics leads to better &lt;strong&gt;testability&lt;/strong&gt;, &lt;strong&gt;scalability&lt;/strong&gt;, and &lt;strong&gt;developer happiness&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;Good architecture grows from &lt;strong&gt;clean, measurable decisions&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🛠 Bonus: Automate It in CI/CD
&lt;/h2&gt;

&lt;p&gt;You can integrate metrics analysis into your DevOps pipeline using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔍 &lt;strong&gt;Roslyn Analyzers&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🧠 &lt;strong&gt;NDepend&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🌊 &lt;strong&gt;SonarQube&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🛠️ &lt;code&gt;dotnet code-quality&lt;/code&gt; tools&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🖼️ &lt;em&gt;Image: CI/CD Quality Gate Flowchart&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Show code → build → analyze → quality gate → deploy.&lt;/em&gt;&lt;/p&gt;




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

&lt;p&gt;Taking time to analyze and improve code complexity today will save you countless hours of debugging and scaling pain tomorrow. Start small—run metrics on one class per sprint.&lt;/p&gt;

&lt;p&gt;🔁 Refactor. 🔬 Measure. ✅ Repeat.&lt;/p&gt;




&lt;p&gt;💬 &lt;strong&gt;How do you manage complexity in your .NET projects? Share your tips below!&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;✍️ &lt;em&gt;Written by Rupinder Kaur, a Senior .NET Developer passionate about clean architecture, refactoring, and continuous improvement.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>analytics</category>
      <category>api</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Code Smells in .NET? Use These Visual Studio Metrics to Refactor Smartly</title>
      <dc:creator>Rupinder Kaur</dc:creator>
      <pubDate>Thu, 05 Feb 2026 03:36:26 +0000</pubDate>
      <link>https://dev.to/rupinder_kaur_6730d267d5f/code-smells-in-net-use-these-visual-studio-metrics-to-refactor-smartly-16cj</link>
      <guid>https://dev.to/rupinder_kaur_6730d267d5f/code-smells-in-net-use-these-visual-studio-metrics-to-refactor-smartly-16cj</guid>
      <description>&lt;p&gt;Have you ever opened an API controller and thought, “Whoa, this looks like spaghetti”? If you’re working with legacy .NET projects or scaling up a growing codebase, complexity can creep in quickly. That’s where &lt;strong&gt;Visual Studio’s Code Metrics&lt;/strong&gt; come to the rescue.&lt;/p&gt;

&lt;p&gt;In this post, I’ll walk you through:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What each code metric means
&lt;/li&gt;
&lt;li&gt;How to use them to identify messy code
&lt;/li&gt;
&lt;li&gt;A real-life example of refactoring a bloated API controller
&lt;/li&gt;
&lt;li&gt;A checklist to guide your review process&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s dive in!&lt;/p&gt;

&lt;h2&gt;
  
  
  What Are Code Metrics?
&lt;/h2&gt;

&lt;p&gt;Code metrics help quantify how maintainable, complex, and testable your code is. Visual Studio provides these metrics via:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Analyze → Analyze Code Metrics
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🖼️ &lt;em&gt;Image: Visual Studio Code Metrics Panel&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;A screenshot of Visual Studio’s Code Metrics results showing Maintainability Index, Cyclomatic Complexity, etc.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Metrics Explained
&lt;/h2&gt;

&lt;p&gt;Here’s what each metric means and why it matters:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Maintainability Index (MI)&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Definition&lt;/strong&gt;: A numeric score (0–100) indicating how easy it is to maintain a code element.&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;80–100&lt;/strong&gt;: Easy to maintain
&lt;/li&gt;
&lt;li&gt;⚠️ &lt;strong&gt;50–79&lt;/strong&gt;: Moderate
&lt;/li&gt;
&lt;li&gt;❌ &lt;strong&gt;0–49&lt;/strong&gt;: Hard to maintain&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;Cyclomatic Complexity (CC)&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Definition&lt;/strong&gt;: The number of independent paths through the code. Increases with &lt;code&gt;if&lt;/code&gt;, &lt;code&gt;switch&lt;/code&gt;, &lt;code&gt;for&lt;/code&gt;, etc.&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;&amp;lt;10&lt;/strong&gt;: Simple
&lt;/li&gt;
&lt;li&gt;⚠️ &lt;strong&gt;10–20&lt;/strong&gt;: Moderate
&lt;/li&gt;
&lt;li&gt;❌ &lt;strong&gt;&amp;gt;20&lt;/strong&gt;: Complex&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. &lt;strong&gt;Depth of Inheritance&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Definition&lt;/strong&gt;: The number of class levels above the current class in the hierarchy.&lt;/li&gt;
&lt;li&gt;✅ 0–3: Ideal
&lt;/li&gt;
&lt;li&gt;❌ &amp;gt;4: May be problematic&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. &lt;strong&gt;Class Coupling&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Definition&lt;/strong&gt;: Number of external classes/types referenced.&lt;/li&gt;
&lt;li&gt;✅ &amp;lt;10: Low coupling (preferred)
&lt;/li&gt;
&lt;li&gt;❌ &amp;gt;20: High coupling (bad for maintainability)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. &lt;strong&gt;Lines of Executable Code&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Definition&lt;/strong&gt;: Number of actual executable lines of code (ignores comments/braces).&lt;/li&gt;
&lt;li&gt;✅ &amp;lt;200 per class, &amp;lt;50 per method
&lt;/li&gt;
&lt;li&gt;❌ &amp;gt;500: Too complex, consider breaking apart&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🖼️ &lt;em&gt;Image: Metric Definitions Heatmap Table&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;A visual summary showing good, warning, and bad ranges for each metric (green-yellow-red).&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Metrics Review Checklist
&lt;/h2&gt;

&lt;p&gt;Here’s a handy checklist to evaluate your API controllers or classes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MI &amp;lt; 50?&lt;/strong&gt; Refactor needed!&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CC &amp;gt; 10?&lt;/strong&gt; Simplify or extract methods.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inheritance depth &amp;gt; 3?&lt;/strong&gt; Consider flattening it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Class coupling &amp;gt; 10?&lt;/strong&gt; Break dependencies, inject interfaces.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Too many LOC?&lt;/strong&gt; Break into smaller classes/services.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Real-Life Example: Refactoring a Bloated API Controller
&lt;/h2&gt;

&lt;p&gt;Let’s say you have this &lt;code&gt;OrdersController&lt;/code&gt;. Everything works, but the code smells.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrdersController&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ControllerBase&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HttpPost&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IActionResult&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;CreateOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OrderDto&lt;/span&gt; &lt;span class="n"&gt;dto&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dto&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;dto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;BadRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid order"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Customers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FindAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CustomerId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;NotFound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Customer not found"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Order&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;CustomerId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CustomerId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;CreatedAt&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UtcNow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Items&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;OrderItem&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;ProductId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ProductId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;Quantity&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Quantity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;Price&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Price&lt;/span&gt;
            &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;ToList&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveChangesAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Order &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; created"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🖼️ &lt;em&gt;Image: OrdersController Before Refactor&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Highlight that business logic, DB operations, and validation are all mixed in the controller.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Code Metrics Report
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;Issue&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Maintainability Index&lt;/td&gt;
&lt;td&gt;47 ❌&lt;/td&gt;
&lt;td&gt;Too low&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cyclomatic Complexity&lt;/td&gt;
&lt;td&gt;15 ⚠️&lt;/td&gt;
&lt;td&gt;Too many branches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Class Coupling&lt;/td&gt;
&lt;td&gt;12 ⚠️&lt;/td&gt;
&lt;td&gt;High dependencies&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Executable LOC&lt;/td&gt;
&lt;td&gt;80 ⚠️&lt;/td&gt;
&lt;td&gt;Too much logic in one method&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Refactoring Plan
&lt;/h3&gt;

&lt;p&gt;We move logic to a new &lt;code&gt;OrderService&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderService&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IOrderService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;CreateOrderAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OrderDto&lt;/span&gt; &lt;span class="n"&gt;dto&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Customers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FindAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CustomerId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                      &lt;span class="p"&gt;??&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Customer not found"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Order&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;CustomerId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CustomerId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;CreatedAt&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UtcNow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Items&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;OrderItem&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;ProductId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ProductId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;Quantity&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Quantity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;Price&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Price&lt;/span&gt;
            &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;ToList&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveChangesAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Order &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; created"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Updated controller:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HttpPost&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IActionResult&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;CreateOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OrderDto&lt;/span&gt; &lt;span class="n"&gt;dto&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;orderId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_orderService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateOrderAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dto&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orderId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Error creating order"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;BadRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🖼️ &lt;em&gt;Image: Refactored Architecture Diagram&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Show controller → service → dbContext pattern (clean layering).&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  After Refactoring Metrics
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;Improvement&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Maintainability Index&lt;/td&gt;
&lt;td&gt;90 ✅&lt;/td&gt;
&lt;td&gt;Big boost&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cyclomatic Complexity&lt;/td&gt;
&lt;td&gt;3 ✅&lt;/td&gt;
&lt;td&gt;Clean logic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Class Coupling&lt;/td&gt;
&lt;td&gt;4 ✅&lt;/td&gt;
&lt;td&gt;Reduced&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Executable LOC&lt;/td&gt;
&lt;td&gt;20 ✅&lt;/td&gt;
&lt;td&gt;Much leaner&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  🖼️ &lt;em&gt;Image: Before vs After Metrics Bar Chart&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Visual comparison of metric values before and after refactoring.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Metrics are &lt;strong&gt;not just numbers&lt;/strong&gt;—they’re clues to identify code smells.
&lt;/li&gt;
&lt;li&gt;Refactoring based on metrics leads to better &lt;strong&gt;testability&lt;/strong&gt;, &lt;strong&gt;scalability&lt;/strong&gt;, and &lt;strong&gt;developer happiness&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;Good architecture grows from &lt;strong&gt;clean, measurable decisions&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Bonus: Automate It in CI/CD
&lt;/h2&gt;

&lt;p&gt;You can integrate metrics analysis into your DevOps pipeline using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔍 &lt;strong&gt;Roslyn Analyzers&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🧠 &lt;strong&gt;NDepend&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🌊 &lt;strong&gt;SonarQube&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🛠️ &lt;code&gt;dotnet code-quality&lt;/code&gt; tools&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🖼️ &lt;em&gt;Image: CI/CD Quality Gate Flowchart&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Show code → build → analyze → quality gate → deploy.&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;Taking time to analyze and improve code complexity today will save you countless hours of debugging and scaling pain tomorrow. Start small—run metrics on one class per sprint.&lt;/p&gt;

&lt;p&gt;🔁 Refactor. 🔬 Measure. ✅ Repeat.&lt;/p&gt;




&lt;p&gt;💬 &lt;strong&gt;How do you manage complexity in your .NET projects? Share your tips below!&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;✍️ &lt;em&gt;Written by Rupinder Kaur, a Senior .NET Developer passionate about clean architecture, refactoring, and continuous improvement.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>refactoring</category>
      <category>dotnet</category>
      <category>csharp</category>
      <category>cleancode</category>
    </item>
    <item>
      <title>Simplify Your .NET Codebase: A Guide to Code Metrics and Controller Refactoring</title>
      <dc:creator>Rupinder Kaur</dc:creator>
      <pubDate>Thu, 24 Jul 2025 19:10:39 +0000</pubDate>
      <link>https://dev.to/rupinder_kaur_6730d267d5f/simplify-your-net-codebase-a-guide-to-code-metrics-and-controller-refactoring-2a04</link>
      <guid>https://dev.to/rupinder_kaur_6730d267d5f/simplify-your-net-codebase-a-guide-to-code-metrics-and-controller-refactoring-2a04</guid>
      <description>&lt;p&gt;Have you ever opened an API controller and thought, “Whoa, this looks like spaghetti”? If you’re working with legacy .NET projects or scaling up a growing codebase, complexity can creep in quickly. That’s where &lt;strong&gt;Visual Studio’s Code Metrics&lt;/strong&gt; come to the rescue.&lt;/p&gt;

&lt;p&gt;In this post, I’ll walk you through:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What each code metric means
&lt;/li&gt;
&lt;li&gt;How to use them to identify messy code
&lt;/li&gt;
&lt;li&gt;A real-life example of refactoring a bloated API controller
&lt;/li&gt;
&lt;li&gt;A checklist to guide your review process&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s dive in!&lt;/p&gt;

&lt;h2&gt;
  
  
  What Are Code Metrics?
&lt;/h2&gt;

&lt;p&gt;Code metrics help quantify how maintainable, complex, and testable your code is. Visual Studio provides these metrics via:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Analyze → Analyze Code Metrics
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd2wsvvx0t9bh776j3g5u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd2wsvvx0t9bh776j3g5u.png" alt="VS code metrics" width="800" height="229"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Metrics Explained
&lt;/h2&gt;

&lt;p&gt;Here’s what each metric means and why it matters:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Maintainability Index (MI)&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Definition&lt;/strong&gt;: A numeric score (0–100) indicating how easy it is to maintain a code element.&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;80–100&lt;/strong&gt;: Easy to maintain
&lt;/li&gt;
&lt;li&gt;⚠️ &lt;strong&gt;50–79&lt;/strong&gt;: Moderate
&lt;/li&gt;
&lt;li&gt;❌ &lt;strong&gt;0–49&lt;/strong&gt;: Hard to maintain&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;Cyclomatic Complexity (CC)&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Definition&lt;/strong&gt;: The number of independent paths through the code. Increases with &lt;code&gt;if&lt;/code&gt;, &lt;code&gt;switch&lt;/code&gt;, &lt;code&gt;for&lt;/code&gt;, etc.&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;&amp;lt;10&lt;/strong&gt;: Simple
&lt;/li&gt;
&lt;li&gt;⚠️ &lt;strong&gt;10–20&lt;/strong&gt;: Moderate
&lt;/li&gt;
&lt;li&gt;❌ &lt;strong&gt;&amp;gt;20&lt;/strong&gt;: Complex&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. &lt;strong&gt;Depth of Inheritance&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Definition&lt;/strong&gt;: The number of class levels above the current class in the hierarchy.&lt;/li&gt;
&lt;li&gt;✅ 0–3: Ideal
&lt;/li&gt;
&lt;li&gt;❌ &amp;gt;4: May be problematic&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. &lt;strong&gt;Class Coupling&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Definition&lt;/strong&gt;: Number of external classes/types referenced.&lt;/li&gt;
&lt;li&gt;✅ &amp;lt;10: Low coupling (preferred)
&lt;/li&gt;
&lt;li&gt;❌ &amp;gt;20: High coupling (bad for maintainability)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. &lt;strong&gt;Lines of Executable Code&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Definition&lt;/strong&gt;: Number of actual executable lines of code (ignores comments/braces).&lt;/li&gt;
&lt;li&gt;✅ &amp;lt;200 per class, &amp;lt;50 per method
&lt;/li&gt;
&lt;li&gt;❌ &amp;gt;500: Too complex, consider breaking apart&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Code Metrics Review Checklist
&lt;/h2&gt;

&lt;p&gt;Here’s a handy checklist to evaluate your API controllers or classes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MI &amp;lt; 50?&lt;/strong&gt; Refactor needed!&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CC &amp;gt; 10?&lt;/strong&gt; Simplify or extract methods.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inheritance depth &amp;gt; 3?&lt;/strong&gt; Consider flattening it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Class coupling &amp;gt; 10?&lt;/strong&gt; Break dependencies, inject interfaces.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Too many LOC?&lt;/strong&gt; Break into smaller classes/services.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Real-Life Example: Refactoring a Bloated API Controller
&lt;/h2&gt;

&lt;p&gt;Let’s say you have this &lt;code&gt;OrdersController&lt;/code&gt;. Everything works, but the code smells.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrdersController&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ControllerBase&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HttpPost&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IActionResult&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;CreateOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OrderDto&lt;/span&gt; &lt;span class="n"&gt;dto&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dto&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;dto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;BadRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid order"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Customers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FindAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CustomerId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;NotFound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Customer not found"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Order&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;CustomerId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CustomerId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;CreatedAt&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UtcNow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Items&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;OrderItem&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;ProductId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ProductId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;Quantity&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Quantity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;Price&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Price&lt;/span&gt;
            &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;ToList&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveChangesAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Order &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; created"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Code Metrics Report
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;Issue&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Maintainability Index&lt;/td&gt;
&lt;td&gt;47 ❌&lt;/td&gt;
&lt;td&gt;Too low&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cyclomatic Complexity&lt;/td&gt;
&lt;td&gt;15 ⚠️&lt;/td&gt;
&lt;td&gt;Too many branches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Class Coupling&lt;/td&gt;
&lt;td&gt;12 ⚠️&lt;/td&gt;
&lt;td&gt;High dependencies&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Executable LOC&lt;/td&gt;
&lt;td&gt;80 ⚠️&lt;/td&gt;
&lt;td&gt;Too much logic in one method&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Refactoring Plan
&lt;/h3&gt;

&lt;p&gt;We move logic to a new &lt;code&gt;OrderService&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderService&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IOrderService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;CreateOrderAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OrderDto&lt;/span&gt; &lt;span class="n"&gt;dto&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Customers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FindAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CustomerId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                      &lt;span class="p"&gt;??&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Customer not found"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Order&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;CustomerId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CustomerId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;CreatedAt&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UtcNow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Items&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;OrderItem&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;ProductId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ProductId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;Quantity&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Quantity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;Price&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Price&lt;/span&gt;
            &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;ToList&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveChangesAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Order &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; created"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Updated controller:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HttpPost&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IActionResult&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;CreateOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OrderDto&lt;/span&gt; &lt;span class="n"&gt;dto&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;orderId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_orderService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateOrderAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dto&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orderId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Error creating order"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;BadRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  After Refactoring Metrics
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;Improvement&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Maintainability Index&lt;/td&gt;
&lt;td&gt;90 ✅&lt;/td&gt;
&lt;td&gt;Big boost&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cyclomatic Complexity&lt;/td&gt;
&lt;td&gt;3 ✅&lt;/td&gt;
&lt;td&gt;Clean logic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Class Coupling&lt;/td&gt;
&lt;td&gt;4 ✅&lt;/td&gt;
&lt;td&gt;Reduced&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Executable LOC&lt;/td&gt;
&lt;td&gt;20 ✅&lt;/td&gt;
&lt;td&gt;Much leaner&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Metrics are &lt;strong&gt;not just numbers&lt;/strong&gt;—they’re clues to identify code smells.
&lt;/li&gt;
&lt;li&gt;Refactoring based on metrics leads to better &lt;strong&gt;testability&lt;/strong&gt;, &lt;strong&gt;scalability&lt;/strong&gt;, and &lt;strong&gt;developer happiness&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;Good architecture grows from &lt;strong&gt;clean, measurable decisions&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Bonus: Automate It in CI/CD
&lt;/h2&gt;

&lt;p&gt;You can integrate metrics analysis into your DevOps pipeline using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Roslyn Analyzers &lt;/li&gt;
&lt;li&gt;NDepend
&lt;/li&gt;
&lt;li&gt;SonarQube
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;dotnet code-quality&lt;/code&gt; tools&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Taking time to analyze and improve code complexity today will save you countless hours of debugging and scaling pain tomorrow. Start small—run metrics on one class per sprint.&lt;/p&gt;

&lt;p&gt;🔁 Refactor. 🔬 Measure. ✅ Repeat.&lt;/p&gt;

&lt;p&gt;💬 &lt;strong&gt;How do you manage complexity in your .NET projects? Share your tips below!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>cleancode</category>
      <category>refactoring</category>
      <category>csharp</category>
    </item>
    <item>
      <title>Demystifying SQL Indexes: A Beginner-to-Advanced Guide with Real-Life Examples</title>
      <dc:creator>Rupinder Kaur</dc:creator>
      <pubDate>Thu, 03 Jul 2025 20:22:08 +0000</pubDate>
      <link>https://dev.to/rupinder_kaur_6730d267d5f/demystifying-sql-indexes-a-beginner-to-advanced-guide-with-real-life-examples-2ikc</link>
      <guid>https://dev.to/rupinder_kaur_6730d267d5f/demystifying-sql-indexes-a-beginner-to-advanced-guide-with-real-life-examples-2ikc</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Master the art of SQL indexes — from the ground up — using real-world analogies, visuals, and hands-on insights.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you're a developer, data analyst, or DBA who's ever asked:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“Why is this query so slow?”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Chances are... &lt;strong&gt;you’re missing the right index&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In this post, we’ll walk through SQL indexes from scratch, building up to best practices, types of indexes, query performance plans, and even real-life cases using the &lt;strong&gt;Query Store&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is an Index (in plain English)?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Think of an index as a &lt;strong&gt;book's table of contents&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you want to find "Chapter 9: Advanced SQL", would you flip every page? No way. You’d look at the index, find the page number, and jump right to it.&lt;/p&gt;

&lt;p&gt;💡 In SQL, an &lt;strong&gt;index&lt;/strong&gt; is a &lt;strong&gt;lookup mechanism&lt;/strong&gt; that helps the database &lt;strong&gt;find rows faster&lt;/strong&gt; without scanning the entire table.&lt;/p&gt;

&lt;h2&gt;
  
  
  Without vs With Index: Real-Life Query Example
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Without index: SQL scans entire table&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'J.K. Rowling'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- With index on author column: SQL does a fast lookup&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;NONCLUSTERED&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_books_author&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Types of SQL Indexes (with Examples)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Index Type&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;SQL Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Clustered Index&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Sorts the actual table data&lt;/td&gt;
&lt;td&gt;(Usually on the primary key)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Non-Clustered Index&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Creates a separate lookup structure&lt;/td&gt;
&lt;td&gt;&lt;code&gt;CREATE NONCLUSTERED INDEX idx_title ON books(title);&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Composite Index&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Index on multiple columns&lt;/td&gt;
&lt;td&gt;&lt;code&gt;CREATE INDEX idx_author_genre ON books(author, genre);&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Unique Index&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Ensures column values are unique&lt;/td&gt;
&lt;td&gt;&lt;code&gt;CREATE UNIQUE INDEX idx_unique_email ON users(email);&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Filtered Index&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Applies to rows that meet a condition&lt;/td&gt;
&lt;td&gt;&lt;code&gt;CREATE INDEX idx_active_books ON books(status) WHERE status = 'Available';&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Full-Text Index&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;For keyword searches on text&lt;/td&gt;
&lt;td&gt;Useful in search engines or blogs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;XML / Spatial Index&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;For XML and geospatial data&lt;/td&gt;
&lt;td&gt;Special use cases&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Index in Action: Clustered Index Scan vs Seek
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Use SQL Server’s &lt;strong&gt;Execution Plan&lt;/strong&gt; to understand if your query is using indexes correctly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Index Seek&lt;/strong&gt; = Fast, precise lookup ✅
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Index Scan&lt;/strong&gt; = Scans part or full index ❌
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clustered Index Scan&lt;/strong&gt; = Scans entire table ❌❌&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Use &lt;code&gt;Ctrl+M&lt;/code&gt; in SSMS before executing your query to see the plan.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'J.K. Rowling'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;With index on &lt;code&gt;author&lt;/code&gt;: &lt;strong&gt;Index Seek&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Without index: &lt;strong&gt;Clustered Index Scan&lt;/strong&gt; (slow)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tools to Analyze Index Usage
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;What It Does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Execution Plan Viewer (SSMS)&lt;/td&gt;
&lt;td&gt;Shows scans/seeks and cost&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sp_helpindex 'table'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Lists all indexes on a table&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sys.dm_db_index_usage_stats&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Tracks index usage metrics&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Query Store&lt;/td&gt;
&lt;td&gt;Captures performance history, regressions, and lets you force good plans&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Query Store Real-Life Scenario: Regressed Query
&lt;/h2&gt;

&lt;p&gt;Imagine this scenario in your e-commerce app:&lt;/p&gt;

&lt;h3&gt;
  
  
  Week 1:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'J.K. Rowling'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;-- Fast: Index Seek used&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Week 3:
&lt;/h3&gt;

&lt;p&gt;Same query, but now...&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ Suddenly runs slower. Why?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;SQL may have &lt;strong&gt;changed the execution plan&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Use Query Store → &lt;strong&gt;Regressed Queries&lt;/strong&gt; in SSMS to find that the &lt;strong&gt;plan regressed&lt;/strong&gt; from Seek → Scan.&lt;/p&gt;

&lt;p&gt;🎯 Fix: Add or rebuild index, or &lt;strong&gt;force the old (faster) plan&lt;/strong&gt; from Query Store.&lt;/p&gt;

&lt;h2&gt;
  
  
  When Should You Create an Index?
&lt;/h2&gt;

&lt;p&gt;Ask these questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Does this column appear frequently in &lt;code&gt;WHERE&lt;/code&gt;, &lt;code&gt;JOIN&lt;/code&gt;, or &lt;code&gt;ORDER BY&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;Is the query slow without an index? (Check execution plan!)&lt;/li&gt;
&lt;li&gt;Are you doing &lt;strong&gt;point lookups&lt;/strong&gt; or &lt;strong&gt;range queries&lt;/strong&gt;?&lt;/li&gt;
&lt;li&gt;Does the table have millions of rows?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Don’t index:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Columns with &lt;strong&gt;very low cardinality&lt;/strong&gt; (e.g., status = 'Active')&lt;/li&gt;
&lt;li&gt;Frequently updated columns (high write cost)&lt;/li&gt;
&lt;li&gt;Too many indexes (every insert/update/delete becomes expensive)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Pro Tips for Index Design
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tip&lt;/th&gt;
&lt;th&gt;Why It Matters&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Always analyze with the Execution Plan&lt;/td&gt;
&lt;td&gt;Confirm if index is used&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use &lt;strong&gt;composite indexes&lt;/strong&gt; when filtering on multiple columns&lt;/td&gt;
&lt;td&gt;E.g., &lt;code&gt;WHERE author = 'A' AND genre = 'B'&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Don’t blindly create indexes&lt;/td&gt;
&lt;td&gt;Use &lt;code&gt;sys.dm_db_index_usage_stats&lt;/code&gt; to see if they’re used&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Clean up unused indexes&lt;/td&gt;
&lt;td&gt;They slow down DML (Insert/Update/Delete)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use &lt;strong&gt;Query Store&lt;/strong&gt; to spot regressions or force good plans&lt;/td&gt;
&lt;td&gt;Especially after deployments or data growth&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  BONUS: How to Test Index Performance
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Optionally recompile to avoid cached plan&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Agatha Christie'&lt;/span&gt;
&lt;span class="k"&gt;OPTION&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RECOMPILE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Execution Plan: Clustered Scan vs Seek&lt;/li&gt;
&lt;li&gt;Query Store: See duration trend over time&lt;/li&gt;
&lt;li&gt;Index usage stats DMV&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion: Indexing Isn’t Magic — It’s Smart Design
&lt;/h2&gt;

&lt;p&gt;You don’t need to memorize syntax — you need to &lt;strong&gt;understand the principles&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How SQL searches data&lt;/li&gt;
&lt;li&gt;How indexes accelerate or hinder performance&lt;/li&gt;
&lt;li&gt;How to analyze and tune your queries like a pro&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you design indexes intentionally — and test them properly — you’ll unlock &lt;strong&gt;blazing fast&lt;/strong&gt; SQL performance and become your team’s database hero. &lt;/p&gt;




&lt;p&gt;📢 If you found this helpful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;💬 Drop a comment&lt;/li&gt;
&lt;li&gt;🧵 Follow me here on Dev.to and &lt;a href="//www.linkedin.com/in/rupinder-srsoftwaredeveloper"&gt;LinkedIn&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>sql</category>
      <category>performance</category>
      <category>beginners</category>
      <category>database</category>
    </item>
    <item>
      <title>Hosting Your ASP.NET Core MVC App on Azure for Free</title>
      <dc:creator>Rupinder Kaur</dc:creator>
      <pubDate>Fri, 27 Jun 2025 13:30:12 +0000</pubDate>
      <link>https://dev.to/rupinder_kaur_6730d267d5f/hosting-your-aspnet-core-mvc-app-on-azure-for-free-3g0d</link>
      <guid>https://dev.to/rupinder_kaur_6730d267d5f/hosting-your-aspnet-core-mvc-app-on-azure-for-free-3g0d</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Whenever you're building an application that requires authentication, you might wonder how to host it online - especially without incurring costs. One powerful way to achieve this is by deploying it to a cloud platform like Azure.&lt;/p&gt;

&lt;p&gt;This post walks you through how to host your ASP.NET Core MVC application on Azure's Free App Service Tier using GitHub for CI/CD, secure app settings, and modern cloud tools - all at zero cost.&lt;/p&gt;

&lt;p&gt;Whether you're building a portfolio, side project, or want production-ready experience, this guide will get you there step-by-step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before we get started:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;ASP.NET Core MVC app with Identity &amp;amp; Tailwind&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Visual Studio 2022+ or VS Code&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;.NET SDK 7 or later&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GitHub account (with repo for your app)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Azure account (Free Tier: &lt;a href="https://azure.microsoft.com/free" rel="noopener noreferrer"&gt;https://azure.microsoft.com/free&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 2: Prepare Your App for Azure Deployment
&lt;/h2&gt;

&lt;p&gt;Clean up and prepare your app:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Remove debug/seed-only code&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add appsettings.Production.json for logs, etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Store secrets using dotnet user-secrets&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet user-secrets set "Authentication:Google:ClientId" "your-client-id"

dotnet user-secrets set "Authentication:Google:ClientSecret" "your-client-secret"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run a local publish to confirm it’s build-ready:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet publish -c Release
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzyjmjw899nlaowx6x86w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzyjmjw899nlaowx6x86w.png" alt="published folder" width="800" height="514"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Set Up Azure App Service
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Go to Azure Portal → Create Resource → App Service&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fill required fields:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Name&lt;/td&gt;
&lt;td&gt;expenseManagement-yourname&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stack&lt;/td&gt;
&lt;td&gt;.NET 7 or later&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OS&lt;/td&gt;
&lt;td&gt;Linux or Windows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Region&lt;/td&gt;
&lt;td&gt;your closest location&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Plan&lt;/td&gt;
&lt;td&gt;F1 (Free Tier)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsvfgzrhmnh1iuxzl4j2r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsvfgzrhmnh1iuxzl4j2r.png" alt="create app service" width="800" height="869"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click “Create” and wait for deployment to complete.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Connect to GitHub for Continuous Deployment
&lt;/h2&gt;

&lt;p&gt;Go to Azure Portal → App Service → Deployment Center and fill the below information:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Source: GitHub&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Build: GitHub Actions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Repo: your project&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Branch: main or master&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This auto-generates a GitHub Actions YAML file that builds and deploys on every push!&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Configure App Settings &amp;amp; Secrets in Azure
&lt;/h2&gt;

&lt;p&gt;In Azure → App Service → Configuration:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Authentication:Google:ClientId&lt;/td&gt;
&lt;td&gt;your-client-id&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Authentication:Google:ClientSecret&lt;/td&gt;
&lt;td&gt;your-client-secret&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ConnectionStrings:DefaultConnection&lt;/td&gt;
&lt;td&gt;SQL Server conn string (if used)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ASPNETCORE_ENVIRONMENT&lt;/td&gt;
&lt;td&gt;Production&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;After saving, restart the app to apply changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6: Test Your Deployed App Live
&lt;/h2&gt;

&lt;p&gt;Your site is now live at:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://your-app-name.azurewebsites.net
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;UI, navigation, Tailwind styles&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OAuth login (Google)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Identity and user creation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DB entries &amp;amp; logs&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion &amp;amp; What's Next
&lt;/h2&gt;

&lt;p&gt;Congratulations! 🎉 Your ASP.NET Core MVC app is now hosted in the cloud - securely and for free.&lt;/p&gt;

&lt;p&gt;You've learned how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Deploy to Azure's Free App Service Tier&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Connect CI/CD with GitHub Actions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Secure secrets using App Settings&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Push real projects live to the web&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;📢 If you found this helpful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;💬 Drop a comment&lt;/li&gt;
&lt;li&gt;🧵 Follow me here on Dev.to and &lt;a href="//www.linkedin.com/in/rupinder-srsoftwaredeveloper"&gt;LinkedIn&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>dotnet</category>
      <category>azure</category>
      <category>devops</category>
      <category>github</category>
    </item>
    <item>
      <title>Secure .NET App with Google Authentication (Step-by-Step)</title>
      <dc:creator>Rupinder Kaur</dc:creator>
      <pubDate>Fri, 20 Jun 2025 16:55:33 +0000</pubDate>
      <link>https://dev.to/rupinder_kaur_6730d267d5f/secure-net-app-with-google-authentication-step-by-step-4c0f</link>
      <guid>https://dev.to/rupinder_kaur_6730d267d5f/secure-net-app-with-google-authentication-step-by-step-4c0f</guid>
      <description>&lt;p&gt;When building a web app with login functionality, you’ll often wonder how to handle authentication securely and efficiently. External login providers like Google, Facebook, and LinkedIn offer users a seamless and trusted sign-in experience. Integrating Google login enhances security via OAuth 2.0 and saves you from managing passwords. It also improves usability by letting users log in with accounts they already use.&lt;br&gt;&lt;br&gt;
This guide walks you through adding Google authentication to your ASP.NET Core MVC app step by step.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 1: Create an ASP.NET Core MVC Project with Identity
&lt;/h3&gt;

&lt;p&gt;Let’s start by creating the ASP.NET Core MVC application that we’ll be working with.&lt;/p&gt;

&lt;p&gt;Follow these steps using Visual Studio:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open Visual Studio 2022 or later.
&lt;/li&gt;
&lt;li&gt;Click on &lt;strong&gt;Create a new project&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;In the project template list, select &lt;strong&gt;ASP.NET Core Web App (Model-View-Controller)&lt;/strong&gt;.
👉 Tip: You can search “mvc” in the search box to find it quickly.
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Next&lt;/strong&gt;.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhxgvtofpbmsa7sk5ttbj.png" alt="Choose Project template" width="800" height="492"&gt;
&lt;/li&gt;
&lt;li&gt;Give your project a name, such as &lt;code&gt;JobTracker&lt;/code&gt; or &lt;code&gt;JobApplicationPortal&lt;/code&gt;.
&lt;/li&gt;
&lt;li&gt;Choose a location on your computer where the project should be saved, then click &lt;strong&gt;Next&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;On the Additional Information screen:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Target Framework&lt;/strong&gt;: .NET 7 or later
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authentication Type&lt;/strong&gt;: Individual Accounts
&lt;/li&gt;
&lt;li&gt;Ensure &lt;strong&gt;Configure for HTTPS&lt;/strong&gt; is checked
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftsrh66wg5t1fjflbrfve.png" alt="Additional information screen when creating project in Visual Studio 2022" width="800" height="533"&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once the project is created, run it using &lt;code&gt;Ctrl + F5&lt;/code&gt;. You should see a default ASP.NET Core MVC homepage with &lt;strong&gt;Register&lt;/strong&gt; and &lt;strong&gt;Login&lt;/strong&gt; links — this means Identity is successfully configured.&lt;/p&gt;

&lt;p&gt;✅ Great! Now that your project is set up, let’s move on to installing the required packages to support Google login.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 2: Install Required NuGet Packages
&lt;/h3&gt;

&lt;p&gt;To enable Google login, first install the necessary authentication packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Install-Package Microsoft.AspNetCore.Authentication.Google
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also ensure you already have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Install-Package Microsoft.AspNetCore.Identity.EntityFrameworkCore
Install-Package Microsoft.AspNetCore.Identity.UI
Install-Package Microsoft.EntityFrameworkCore.SqlServer
Install-Package Microsoft.EntityFrameworkCore.Tools
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;💡 These enable ASP.NET Identity, EF Core, and Google OAuth integration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Create Google OAuth Credentials
&lt;/h3&gt;

&lt;p&gt;Head to &lt;a href="https://console.cloud.google.com/" rel="noopener noreferrer"&gt;Google Cloud Console&lt;/a&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a new project&lt;/li&gt;
&lt;li&gt;Enable "Google Identity Services" API&lt;/li&gt;
&lt;li&gt;Go to "OAuth consent screen" → External → Fill app info → Add &lt;code&gt;localhost&lt;/code&gt; as authorized domain&lt;/li&gt;
&lt;li&gt;Create OAuth credentials

&lt;ul&gt;
&lt;li&gt;App type: Web&lt;/li&gt;
&lt;li&gt;Redirect URI: &lt;code&gt;https://localhost:7020/signin-google&lt;/code&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnipf436z4fuuuunda4hk.png" alt="google console for client id creation" width="800" height="757"&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Store your client ID/secret securely using these steps: 

&lt;ul&gt;
&lt;li&gt;Open Visual Studio.&lt;/li&gt;
&lt;li&gt;Right-click your project in Solution Explorer and select &lt;strong&gt;Open in Terminal&lt;/strong&gt; (or use Command Prompt/PowerShell).&lt;/li&gt;
&lt;li&gt; Make sure you're in the folder where your &lt;code&gt;.csproj&lt;/code&gt; file is located.&lt;/li&gt;
&lt;li&gt;Run the following command to initialize user secrets if you haven’t already:
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;/div&gt;



&lt;p&gt;Store your client ID/secret securely using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet user-secrets &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="s2"&gt;"Authentication:Google:ClientId"&lt;/span&gt; &lt;span class="s2"&gt;"your-client-id"&lt;/span&gt;
dotnet user-secrets &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="s2"&gt;"Authentication:Google:ClientSecret"&lt;/span&gt; &lt;span class="s2"&gt;"your-client-secret"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Configure Google Auth in Program.cs
&lt;/h3&gt;

&lt;p&gt;Inside &lt;code&gt;Program.cs&lt;/code&gt;, add Google auth after setting up Identity:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddAuthentication&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddGoogle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ClientId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"Authentication:Google:ClientId"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ClientSecret&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"Authentication:Google:ClientSecret"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fherodc46coye5nd1trfx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fherodc46coye5nd1trfx.png" alt="program.cs file showing code snippet for adding google client id and client secret" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Add Google Login Button in UI
&lt;/h3&gt;

&lt;p&gt;In &lt;code&gt;Areas/Identity/Pages/Account/Login.cshtml&lt;/code&gt;, below your login form, add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"mt-6 border-t pt-4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-sm text-center text-gray-500 mb-4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Or sign in with&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;asp-page=&lt;/span&gt;&lt;span class="s"&gt;"./ExternalLogin"&lt;/span&gt; &lt;span class="na"&gt;asp-route-provider=&lt;/span&gt;&lt;span class="s"&gt;"Google"&lt;/span&gt; &lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;"post"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"w-full"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"hidden"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"returnUrl"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"@Model.ReturnUrl"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"w-full py-2 px-4 bg-red-600 text-white rounded hover:bg-red-700"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      Continue with Google
    &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwhzh9tuiv4txgzjbjd8z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwhzh9tuiv4txgzjbjd8z.png" alt="login screen with sign in with google option" width="800" height="839"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 6: Test the Login Flow
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Run your app → go to /Identity/Account/Login&lt;/li&gt;
&lt;li&gt;Click the Google button → authenticate via Google&lt;/li&gt;
&lt;li&gt;Redirected back to &lt;code&gt;/signin-google&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;ASP.NET Core Identity creates the user if it doesn't exist&lt;/li&gt;
&lt;li&gt;Check &lt;code&gt;AspNetUsers&lt;/code&gt; and &lt;code&gt;AspNetUserLogins&lt;/code&gt; tables in your DB.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnu2zb3amufh7tfg1ymti.png" alt="Google login screen" width="800" height="361"&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Conclusion &amp;amp; What’s Next
&lt;/h3&gt;

&lt;p&gt;Congrats! 🎉 You added Google login to your ASP.NET Core MVC app.&lt;/p&gt;

&lt;p&gt;You now understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to connect Google OAuth to .NET Identity&lt;/li&gt;
&lt;li&gt;How to secure credentials using User Secrets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;📢 If you found this helpful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;💬 Drop a comment&lt;/li&gt;
&lt;li&gt;🧵 Follow me here on Dev.to and &lt;a href="//www.linkedin.com/in/rupinder-srsoftwaredeveloper"&gt;LinkedIn&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s keep building real projects together!&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>beginners</category>
      <category>webdev</category>
      <category>security</category>
    </item>
  </channel>
</rss>
