{"id":236,"date":"2025-07-28T06:16:26","date_gmt":"2025-07-28T06:16:26","guid":{"rendered":"https:\/\/www.dotnetdevelopers.us\/blogs\/?p=236"},"modified":"2025-07-28T06:17:51","modified_gmt":"2025-07-28T06:17:51","slug":"injection-dot-net","status":"publish","type":"post","link":"https:\/\/www.dotnetdevelopers.us\/blogs\/injection-dot-net\/","title":{"rendered":"Dependency Injection in .NET: A Practical Approach Made Simple"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_74 counter-hierarchy ez-toc-counter ez-toc-light-blue ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/www.dotnetdevelopers.us\/blogs\/injection-dot-net\/#_What_is_Dependency_Injection_in_Simple_Words\" >&nbsp;What is Dependency Injection in Simple Words?<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/www.dotnetdevelopers.us\/blogs\/injection-dot-net\/#_A_real-world_analogy\" >&nbsp;A real-world analogy:<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/www.dotnetdevelopers.us\/blogs\/injection-dot-net\/#_Why_Use_Dependency_Injection\" >&nbsp;Why Use Dependency Injection?<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/www.dotnetdevelopers.us\/blogs\/injection-dot-net\/#1_Loose_Coupling\" >1. Loose Coupling<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/www.dotnetdevelopers.us\/blogs\/injection-dot-net\/#2_Better_Testing\" >2. Better Testing<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/www.dotnetdevelopers.us\/blogs\/injection-dot-net\/#3_Cleaner_Code\" >3. Cleaner Code<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/www.dotnetdevelopers.us\/blogs\/injection-dot-net\/#4_Scalability\" >4. Scalability<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/www.dotnetdevelopers.us\/blogs\/injection-dot-net\/#_Basic_Example_Without_DI_The_Hard_Way\" >&nbsp;Basic Example Without DI (The Hard Way)<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/www.dotnetdevelopers.us\/blogs\/injection-dot-net\/#_Whats_wrong_here\" >&nbsp;What\u2019s wrong here?<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/www.dotnetdevelopers.us\/blogs\/injection-dot-net\/#_Same_Example_With_DI_The_Right_Way\" >&nbsp;Same Example With DI (The Right Way)<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/www.dotnetdevelopers.us\/blogs\/injection-dot-net\/#_Benefits\" >&nbsp;Benefits:<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/www.dotnetdevelopers.us\/blogs\/injection-dot-net\/#How_DI_Works_in_NET_Core_and_NET_6\" >How DI Works in .NET Core and .NET 6+<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-13\" href=\"https:\/\/www.dotnetdevelopers.us\/blogs\/injection-dot-net\/#_What_Does_AddScoped_Mean\" >&nbsp;What Does AddScoped Mean?<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-14\" href=\"https:\/\/www.dotnetdevelopers.us\/blogs\/injection-dot-net\/#Real-Life_Example_in_ASPNET_Core\" >Real-Life Example in ASP.NET Core<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-15\" href=\"https:\/\/www.dotnetdevelopers.us\/blogs\/injection-dot-net\/#Step_1_Create_an_Interface_and_Class\" >Step 1: Create an Interface and Class<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-16\" href=\"https:\/\/www.dotnetdevelopers.us\/blogs\/injection-dot-net\/#Step_2_Register_Services_in_Programcs\" >Step 2: Register Services in Program.cs<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-17\" href=\"https:\/\/www.dotnetdevelopers.us\/blogs\/injection-dot-net\/#Step_3_Inject_into_Controller\" >Step 3: Inject into Controller<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-18\" href=\"https:\/\/www.dotnetdevelopers.us\/blogs\/injection-dot-net\/#Types_of_Dependency_Injection\" >Types of Dependency Injection<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-19\" href=\"https:\/\/www.dotnetdevelopers.us\/blogs\/injection-dot-net\/#1_Constructor_Injection_Most_Common\" >1. Constructor Injection (Most Common)<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-20\" href=\"https:\/\/www.dotnetdevelopers.us\/blogs\/injection-dot-net\/#2_Setter_Injection\" >2. Setter Injection<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-21\" href=\"https:\/\/www.dotnetdevelopers.us\/blogs\/injection-dot-net\/#3_Method_Injection\" >3. Method Injection<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-22\" href=\"https:\/\/www.dotnetdevelopers.us\/blogs\/injection-dot-net\/#_When_Should_You_Use_Singleton_Scoped_or_Transient\" >&nbsp;When Should You Use Singleton, Scoped, or Transient?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-23\" href=\"https:\/\/www.dotnetdevelopers.us\/blogs\/injection-dot-net\/#Common_Mistakes_to_Avoid\" >Common Mistakes to Avoid<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-24\" href=\"https:\/\/www.dotnetdevelopers.us\/blogs\/injection-dot-net\/#_Best_Practices_for_DI_in_NET\" >&nbsp;Best Practices for DI in .NET<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-25\" href=\"https:\/\/www.dotnetdevelopers.us\/blogs\/injection-dot-net\/#Unit_Testing_with_DI_%E2%80%93_A_Quick_Example\" >Unit Testing with DI \u2013 A Quick Example<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-26\" href=\"https:\/\/www.dotnetdevelopers.us\/blogs\/injection-dot-net\/#Q1_Is_DI_only_for_web_applications\" >Q1: Is DI only for web applications?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-27\" href=\"https:\/\/www.dotnetdevelopers.us\/blogs\/injection-dot-net\/#Q2_Can_I_inject_multiple_implementations_of_an_interface\" >Q2: Can I inject multiple implementations of an interface?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-28\" href=\"https:\/\/www.dotnetdevelopers.us\/blogs\/injection-dot-net\/#Q3_Is_DI_just_a_NET_thing\" >Q3: Is DI just a .NET thing?<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-29\" href=\"https:\/\/www.dotnetdevelopers.us\/blogs\/injection-dot-net\/#_Wrapping_Things_Up\" >&nbsp;Wrapping Things Up<\/a><\/li><\/ul><\/nav><\/div>\n\n<p>If you\u2019ve been working with .NET (or just started), you\u2019ve probably heard the term Dependency Injection (DI) tossed around like it&#8217;s some secret sauce. The truth? It <em>is<\/em> magical, but not in a mysterious way.<\/p>\n\n\n\n<p>Dependency Injection is all about writing cleaner code, reducing repetition, and making your applications easier to test and maintain. In this article, we\u2019re going to break down DI in the most beginner-friendly way possible, with real examples, simple language, and absolutely zero jargon fluff.<\/p>\n\n\n\n<p>So whether you\u2019re building an ASP.NET Core Web API or a simple console app, you\u2019re in for a real treat.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"_What_is_Dependency_Injection_in_Simple_Words\"><\/span><strong>&nbsp;What is Dependency Injection in Simple Words?<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Alright, let\u2019s strip away the fancy terms.<\/p>\n\n\n\n<p>Imagine you\u2019re baking a cake. Instead of buying eggs, flour, and sugar yourself, someone hands you everything you need, already prepared.<\/p>\n\n\n\n<p>That\u2019s Dependency Injection, you get what you need (dependencies), without creating them yourself.<\/p>\n\n\n\n<p>In programming, a dependency is simply another class or service that your code needs to perform its job. Instead of creating those dependencies directly, you let a system (the DI container) provide them for you.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"_A_real-world_analogy\"><\/span><strong>&nbsp;A real-world analogy:<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>If your car needs an engine to run, do you build the engine every time? Nope! You just install it or get it from a supplier.<\/p>\n\n\n\n<p>In .NET, you don\u2019t \u201cnew-up\u201d (instantiate) everything manually<strong>.<\/strong> DI does it for you.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"_Why_Use_Dependency_Injection\"><\/span><strong>&nbsp;Why Use Dependency Injection?<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>You might wonder, \u201cWhy not just use new everywhere?\u201d Here\u2019s why that\u2019s not ideal:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"1_Loose_Coupling\"><\/span><strong>1. Loose Coupling<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Your classes don\u2019t depend on specific implementations, just contracts (interfaces).<br><\/li>\n\n\n\n<li>Easier to switch components without breaking everything.<br><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"2_Better_Testing\"><\/span><strong>2. Better Testing<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>You can easily inject fake or mock data during unit tests.<br><\/li>\n\n\n\n<li>Makes Test-Driven Development (TDD) a breeze.<br><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"3_Cleaner_Code\"><\/span><strong>3. Cleaner Code<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>No long chains of object creation.<br><\/li>\n\n\n\n<li>Keeps classes focused on doing one thing well.<br><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"4_Scalability\"><\/span><strong>4. Scalability<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>As your app grows, DI helps you manage complexity better.<br><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"_Basic_Example_Without_DI_The_Hard_Way\"><\/span><strong>&nbsp;Basic Example Without DI (The Hard Way)<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>csharp<\/p>\n\n\n\n<p>CopyEdit<\/p>\n\n\n\n<p>public class EmailService<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;public void SendEmail(string message)<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine($&#8221;Sending: {message}&#8221;);<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;}<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>public class Notification<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;private EmailService _emailService = new EmailService();<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;public void NotifyUser(string msg)<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_emailService.SendEmail(msg);<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;}<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"_Whats_wrong_here\"><\/span><strong>&nbsp;What\u2019s wrong here?<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Notification creates its own EmailService.<br><\/li>\n\n\n\n<li>It\u2019s tightly coupled and hard to test or replace.<br><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"_Same_Example_With_DI_The_Right_Way\"><\/span><strong>&nbsp;Same Example With DI (The Right Way)<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>csharp<\/p>\n\n\n\n<p>CopyEdit<\/p>\n\n\n\n<p>public interface IEmailService<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;void SendEmail(string message);<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>public class EmailService: IEmailService<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;public void SendEmail(string message)<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine($&#8221;Sending: {message}&#8221;);<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;}<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>public class Notification<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;private readonly IEmailService _emailService;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;public Notification(IEmailService emailService)<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_emailService = emailService;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;}<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;public void NotifyUser(string msg)<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_emailService.SendEmail(msg);<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;}<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"_Benefits\"><\/span><strong>&nbsp;Benefits:<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>We\u2019re injecting the EmailService.<br><\/li>\n\n\n\n<li>We depend on an interface, not a concrete class.<br><\/li>\n\n\n\n<li>Much easier to test and maintain.<br><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"How_DI_Works_in_NET_Core_and_NET_6\"><\/span><strong>How DI Works in .NET Core and .NET 6+<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>The cool part? .NET Core and .NET 6+ have built-in support for DI out of the box! You don\u2019t need external libraries or complex setups.<\/p>\n\n\n\n<p>Here\u2019s how the DI container works in a typical ASP<a href=\"https:\/\/www.dotnetdevelopers.us\/\" target=\"_blank\" data-type=\"link\" data-id=\"https:\/\/www.dotnetdevelopers.us\/\" rel=\"noreferrer noopener\">.NET<\/a> Core app:<\/p>\n\n\n\n<p>csharp<\/p>\n\n\n\n<p>CopyEdit<\/p>\n\n\n\n<p>public void ConfigureServices(IServiceCollection services)<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;services.AddScoped&lt;IEmailService, EmailService&gt;();<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;services.AddScoped&lt;Notification&gt;();<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"_What_Does_AddScoped_Mean\"><\/span><strong>&nbsp;What Does <\/strong><strong>AddScoped<\/strong><strong> Mean?<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>.NET DI supports three lifetimes:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Transient<\/strong> \u2013 A new instance every time.<br><\/li>\n\n\n\n<li><strong>Scoped<\/strong> \u2013 One instance per HTTP request.<br><\/li>\n\n\n\n<li><strong>Singleton<\/strong> \u2013 One instance for the whole app.<br><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Real-Life_Example_in_ASPNET_Core\"><\/span><strong>Real-Life Example in ASP.NET Core<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Let\u2019s say we\u2019re building an API that sends email notifications.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Step_1_Create_an_Interface_and_Class\"><\/span><strong>Step 1: Create an Interface and Class<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>csharp<\/p>\n\n\n\n<p>CopyEdit<\/p>\n\n\n\n<p>public interface IEmailService<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;void SendEmail(string message);<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>public class EmailService: IEmailService<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;public void SendEmail(string message)<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine($&#8221;Email sent: {message}&#8221;);<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;}<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Step_2_Register_Services_in_Programcs\"><\/span><strong>Step 2: Register Services in <\/strong><strong>Program.cs<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>csharp<\/p>\n\n\n\n<p>CopyEdit<\/p>\n\n\n\n<p>builder.Services.AddScoped&lt;IEmailService, EmailService&gt;();<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Step_3_Inject_into_Controller\"><\/span><strong>Step 3: Inject into Controller<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>csharp<\/p>\n\n\n\n<p>CopyEdit<\/p>\n\n\n\n<p>[ApiController]<\/p>\n\n\n\n<p>[Route(&#8220;api\/[controller]&#8221;)]<\/p>\n\n\n\n<p>public class NotifyController: ControllerBase<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;private readonly IEmailService _emailService;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;public NotifyController(IEmailService emailService)<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_emailService = emailService;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;}<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;[HttpPost]<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;public IActionResult Send(string message)<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_emailService.SendEmail(message);<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return Ok(&#8220;Message sent!&#8221;);<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;}<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Types_of_Dependency_Injection\"><\/span><strong>Types of Dependency Injection<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>There are three main types of DI:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"1_Constructor_Injection_Most_Common\"><\/span><strong>1. Constructor Injection (Most Common)<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Dependencies are passed through the class constructor.<br><\/li>\n\n\n\n<li>Encourages immutability and clear code.<br><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"2_Setter_Injection\"><\/span><strong>2. Setter Injection<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Dependencies are set via properties.<br><\/li>\n<\/ul>\n\n\n\n<p>csharp<\/p>\n\n\n\n<p>CopyEdit<\/p>\n\n\n\n<p>public class MyService<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;public IEmailService EmailService { get; set; }<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"3_Method_Injection\"><\/span><strong>3. Method Injection<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Dependencies are passed directly into methods.<br><\/li>\n<\/ul>\n\n\n\n<p>csharp<\/p>\n\n\n\n<p>CopyEdit<\/p>\n\n\n\n<p>public void ProcessOrder(IEmailService emailService)<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;emailService.SendEmail(&#8220;Order processed!&#8221;);<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>Constructor Injection is the go-to in most .NET Core apps.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"_When_Should_You_Use_Singleton_Scoped_or_Transient\"><\/span><strong>&nbsp;When Should You Use Singleton, Scoped, or Transient?<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><strong>Lifetime<\/strong><\/td><td><strong>When to Use It<\/strong><\/td><td><strong>Example<\/strong><\/td><\/tr><tr><td>Singleton<\/td><td>App-wide settings, config services<\/td><td>Logging, Config settings<\/td><\/tr><tr><td>Scoped<\/td><td>Per-user or per-request operations<\/td><td>Web API services<\/td><\/tr><tr><td>Transient<\/td><td>Lightweight, short-lived tasks<\/td><td>Helper classes, Utilities<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Common_Mistakes_to_Avoid\"><\/span><strong>Common Mistakes to Avoid<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Not using interfaces<\/strong> \u2013 Always inject by interface, not by concrete class.<br><\/li>\n\n\n\n<li><strong>Registering incorrect lifetimes<\/strong> \u2013 Be cautious with<strong> <\/strong><strong>Singletons<\/strong> in web apps.<br><\/li>\n\n\n\n<li><strong>Over-injecting<\/strong> \u2013 Don\u2019t inject a service just because you can.<br><\/li>\n\n\n\n<li><strong>Tightly coupled services<\/strong> \u2013 Be cautious of services that rely on too many other services.<br><\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"_Best_Practices_for_DI_in_NET\"><\/span><strong>&nbsp;Best Practices for DI in .NET<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Stick with constructor injection for most cases.<br><\/li>\n\n\n\n<li>Use interfaces to maintain testability and flexibility.<br><\/li>\n\n\n\n<li>Avoid service locators (i.e., manually pulling services from the container).<br><\/li>\n\n\n\n<li>Group related services together for readability.<br><\/li>\n\n\n\n<li>Use [FromServices] attribute for optional method injection.<br><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Unit_Testing_with_DI_%E2%80%93_A_Quick_Example\"><\/span><strong>Unit Testing with DI \u2013 A Quick Example<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>You can now mock your dependencies easily!<\/p>\n\n\n\n<p>csharp<\/p>\n\n\n\n<p>CopyEdit<\/p>\n\n\n\n<p>[Fact]<\/p>\n\n\n\n<p>public void ShouldSendEmail()<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;var mockEmail = new Mock&lt;IEmailService&gt;();<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;var notify = new Notification(mockEmail.Object);<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;notify.NotifyUser(&#8220;Hello!&#8221;);<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;mockEmail.Verify(e =&gt; e.SendEmail(&#8220;Hello!&#8221;), Times.Once);<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>Boom! DI makes your code testable with zero fuss.<\/p>\n\n\n\n<p class=\"has-text-align-center has-large-font-size\"><strong>FAQs<\/strong><\/p>\n\n\n<div id=\"rank-math-faq\" class=\"rank-math-block\">\n<div class=\"rank-math-list \">\n<div id=\"faq-question-1753682725802\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question \"><span class=\"ez-toc-section\" id=\"Q1_Is_DI_only_for_web_applications\"><\/span><strong>Q1: Is DI only for web applications?<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<div class=\"rank-math-answer \">\n\n<p>Nope! You can use it in Console Apps, Windows Forms, WPF anywhere in .NET<\/p>\n\n<\/div>\n<\/div>\n<div id=\"faq-question-1753682752000\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question \"><span class=\"ez-toc-section\" id=\"Q2_Can_I_inject_multiple_implementations_of_an_interface\"><\/span>Q2: <strong>Can I inject multiple implementations of an interface?<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<div class=\"rank-math-answer \">\n\n<p>Yes, by using IEnumerable&lt;IService&gt;, or named services via factories.<\/p>\n\n<\/div>\n<\/div>\n<div id=\"faq-question-1753682786086\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question \"><span class=\"ez-toc-section\" id=\"Q3_Is_DI_just_a_NET_thing\"><\/span><strong>Q3: Is DI just a .NET thing?<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<div class=\"rank-math-answer \">\n\n<p>Not at all. DI is a general programming concept used in various programming languages, including Java, Python, and Node.js<\/p>\n\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"_Wrapping_Things_Up\"><\/span><strong>&nbsp;Wrapping Things Up<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>So, there you have it, a beginner-friendly, practical, no-nonsense breakdown of Dependency Injection in  .NET.<\/p>\n\n\n\n<p>Let\u2019s recap the key takeaways:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>DI is about providing your class with the necessary objects, without creating them.<br><\/li>\n\n\n\n<li>It keeps code clean, testable, and easy to maintain.<br><\/li>\n\n\n\n<li>.NET Core\/6+ has built-in support for DI, use it!<br><\/li>\n\n\n\n<li>Stick with constructor injection, register your services properly, and avoid tight coupling.<br><\/li>\n<\/ul>\n\n\n\n<p>Once you get the hang of it, you\u2019ll wonder how you ever coded without it.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you\u2019ve been working with .NET (or just started), you\u2019ve probably heard the term Dependency Injection (DI) tossed around like it&#8217;s some secret sauce. The truth? It is magical, but not in a mysterious way. Dependency Injection is all about writing cleaner code, reducing repetition, and making your applications easier to test and maintain. In this article, we\u2019re going to break down DI in the most beginner-friendly way possible, with real examples, simple language, and absolutely zero jargon fluff. So whether you\u2019re building an ASP.NET Core Web API or a simple console app, you\u2019re in for a real treat. &nbsp;What is Dependency Injection in Simple Words? Alright, let\u2019s strip away the fancy terms. Imagine you\u2019re baking a cake. Instead of buying eggs, flour, and sugar yourself, someone hands you everything you need, already prepared. That\u2019s Dependency Injection, you get what you need (dependencies), without creating them yourself. In programming, a dependency is simply another class or service that your code needs to perform its job. Instead of creating those dependencies directly, you let a system (the DI container) provide them for you. &nbsp;A real-world analogy: If your car needs an engine to run, do you build the engine every time? Nope! You just install it or get it from a supplier. In .NET, you don\u2019t \u201cnew-up\u201d (instantiate) everything manually. DI does it for you. &nbsp;Why Use Dependency Injection? You might wonder, \u201cWhy not just use new everywhere?\u201d Here\u2019s why that\u2019s not ideal: 1. Loose Coupling 2. Better Testing 3. Cleaner Code 4. Scalability &nbsp;Basic Example Without DI (The Hard Way) csharp CopyEdit public class EmailService { &nbsp;&nbsp;&nbsp;&nbsp;public void SendEmail(string message) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine($&#8221;Sending: {message}&#8221;); &nbsp;&nbsp;&nbsp;&nbsp;} } public class Notification { &nbsp;&nbsp;&nbsp;&nbsp;private EmailService _emailService = new EmailService(); &nbsp;&nbsp;&nbsp;&nbsp;public void NotifyUser(string msg) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_emailService.SendEmail(msg); &nbsp;&nbsp;&nbsp;&nbsp;} } &nbsp;What\u2019s wrong here? &nbsp;Same Example With DI (The Right Way) csharp CopyEdit public interface IEmailService { &nbsp;&nbsp;&nbsp;&nbsp;void SendEmail(string message); } public class EmailService: IEmailService { &nbsp;&nbsp;&nbsp;&nbsp;public void SendEmail(string message) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine($&#8221;Sending: {message}&#8221;); &nbsp;&nbsp;&nbsp;&nbsp;} } public class Notification { &nbsp;&nbsp;&nbsp;&nbsp;private readonly IEmailService _emailService; &nbsp;&nbsp;&nbsp;&nbsp;public Notification(IEmailService emailService) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_emailService = emailService; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;public void NotifyUser(string msg) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_emailService.SendEmail(msg); &nbsp;&nbsp;&nbsp;&nbsp;} } &nbsp;Benefits: How DI Works in .NET Core and .NET 6+ The cool part? .NET Core and .NET 6+ have built-in support for DI out of the box! You don\u2019t need external libraries or complex setups. Here\u2019s how the DI container works in a typical ASP.NET Core app: csharp CopyEdit public void ConfigureServices(IServiceCollection services) { &nbsp;&nbsp;&nbsp;&nbsp;services.AddScoped&lt;IEmailService, EmailService&gt;(); &nbsp;&nbsp;&nbsp;&nbsp;services.AddScoped&lt;Notification&gt;(); } &nbsp;What Does AddScoped Mean? .NET DI supports three lifetimes: Real-Life Example in ASP.NET Core Let\u2019s say we\u2019re building an API that sends email notifications. Step 1: Create an Interface and Class csharp CopyEdit public interface IEmailService { &nbsp;&nbsp;&nbsp;&nbsp;void SendEmail(string message); } public class EmailService: IEmailService { &nbsp;&nbsp;&nbsp;&nbsp;public void SendEmail(string message) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine($&#8221;Email sent: {message}&#8221;); &nbsp;&nbsp;&nbsp;&nbsp;} } Step 2: Register Services in Program.cs csharp CopyEdit builder.Services.AddScoped&lt;IEmailService, EmailService&gt;(); Step 3: Inject into Controller csharp CopyEdit [ApiController] [Route(&#8220;api\/[controller]&#8221;)] public class NotifyController: ControllerBase { &nbsp;&nbsp;&nbsp;&nbsp;private readonly IEmailService _emailService; &nbsp;&nbsp;&nbsp;&nbsp;public NotifyController(IEmailService emailService) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_emailService = emailService; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;[HttpPost] &nbsp;&nbsp;&nbsp;&nbsp;public IActionResult Send(string message) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_emailService.SendEmail(message); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return Ok(&#8220;Message sent!&#8221;); &nbsp;&nbsp;&nbsp;&nbsp;} } Types of Dependency Injection There are three main types of DI: 1. Constructor Injection (Most Common) 2. Setter Injection csharp CopyEdit public class MyService { &nbsp;&nbsp;&nbsp;&nbsp;public IEmailService EmailService { get; set; } } 3. Method Injection csharp CopyEdit public void ProcessOrder(IEmailService emailService) { &nbsp;&nbsp;&nbsp;&nbsp;emailService.SendEmail(&#8220;Order processed!&#8221;); } Constructor Injection is the go-to in most .NET Core apps. &nbsp;When Should You Use Singleton, Scoped, or Transient? Lifetime When to Use It Example Singleton App-wide settings, config services Logging, Config settings Scoped Per-user or per-request operations Web API services Transient Lightweight, short-lived tasks Helper classes, Utilities Common Mistakes to Avoid &nbsp;Best Practices for DI in .NET Unit Testing with DI \u2013 A Quick Example You can now mock your dependencies easily! csharp CopyEdit [Fact] public void ShouldSendEmail() { &nbsp;&nbsp;&nbsp;&nbsp;var mockEmail = new Mock&lt;IEmailService&gt;(); &nbsp;&nbsp;&nbsp;&nbsp;var notify = new Notification(mockEmail.Object); &nbsp;&nbsp;&nbsp;&nbsp;notify.NotifyUser(&#8220;Hello!&#8221;); &nbsp;&nbsp;&nbsp;&nbsp;mockEmail.Verify(e =&gt; e.SendEmail(&#8220;Hello!&#8221;), Times.Once); } Boom! DI makes your code testable with zero fuss. FAQs &nbsp;Wrapping Things Up So, there you have it, a beginner-friendly, practical, no-nonsense breakdown of Dependency Injection in .NET. Let\u2019s recap the key takeaways: Once you get the hang of it, you\u2019ll wonder how you ever coded without it.<\/p>\n","protected":false},"author":1,"featured_media":237,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[2],"tags":[],"class_list":["post-236","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development"],"_links":{"self":[{"href":"https:\/\/www.dotnetdevelopers.us\/blogs\/wp-json\/wp\/v2\/posts\/236","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dotnetdevelopers.us\/blogs\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dotnetdevelopers.us\/blogs\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dotnetdevelopers.us\/blogs\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dotnetdevelopers.us\/blogs\/wp-json\/wp\/v2\/comments?post=236"}],"version-history":[{"count":1,"href":"https:\/\/www.dotnetdevelopers.us\/blogs\/wp-json\/wp\/v2\/posts\/236\/revisions"}],"predecessor-version":[{"id":238,"href":"https:\/\/www.dotnetdevelopers.us\/blogs\/wp-json\/wp\/v2\/posts\/236\/revisions\/238"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.dotnetdevelopers.us\/blogs\/wp-json\/wp\/v2\/media\/237"}],"wp:attachment":[{"href":"https:\/\/www.dotnetdevelopers.us\/blogs\/wp-json\/wp\/v2\/media?parent=236"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dotnetdevelopers.us\/blogs\/wp-json\/wp\/v2\/categories?post=236"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dotnetdevelopers.us\/blogs\/wp-json\/wp\/v2\/tags?post=236"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}