<?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: Aleksei Ananev</title>
    <description>The latest articles on DEV Community by Aleksei Ananev (@hypercodeplace).</description>
    <link>https://dev.to/hypercodeplace</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%2F517622%2F5bd6fc72-c51d-4c15-a908-2f9487072c66.JPG</url>
      <title>DEV Community: Aleksei Ananev</title>
      <link>https://dev.to/hypercodeplace</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hypercodeplace"/>
    <language>en</language>
    <item>
      <title>Default Interface Implementations in C#: Where Inheritance Goes to Troll You</title>
      <dc:creator>Aleksei Ananev</dc:creator>
      <pubDate>Mon, 09 Dec 2024 20:40:10 +0000</pubDate>
      <link>https://dev.to/hypercodeplace/default-interface-implementations-in-c-where-inheritance-goes-to-troll-you-2djf</link>
      <guid>https://dev.to/hypercodeplace/default-interface-implementations-in-c-where-inheritance-goes-to-troll-you-2djf</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;C# is a powerful and ever-evolving programming language, loved by developers for its robustness and versatility. With each new version, it introduces features that enhance convenience and streamline development.&lt;/p&gt;

&lt;p&gt;However, much like Peter Parker, developers must wield this power responsibly. One slip-up, and you might find yourself tangled in a web of bugs and confusion.&lt;/p&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%2Flhx5v33i6ctwz6mc522l.jpg" 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%2Flhx5v33i6ctwz6mc522l.jpg" alt="With great power comes great debugging sessions" width="586" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A prime example of this is &lt;a href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-8.0/default-interface-methods" rel="noopener noreferrer"&gt;Default Interface Implementations&lt;/a&gt;, introduced in C# 8.0. This feature allows developers to define methods with default implementations directly in interfaces. While it enables smoother API evolution by allowing methods to be added without breaking existing implementations and improves C#'s interoperation with platforms like Android (Java) and iOS (Swift), it also opens the door to subtle, hard-to-detect bugs, especially when combined with inheritance and dependency injection.&lt;/p&gt;

&lt;p&gt;In this article, we’ll explore a seemingly straightforward scenario where Default Interface Implementations swing into action, only to deliver a surprise ending. This topic was inspired by a recent situation I encountered in my own practice, which highlighted how easily things can go awry. We’ll unravel the technical reasons behind this unexpected behavior and share tips to ensure your code doesn’t fall into the same trap.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Simple Service
&lt;/h2&gt;

&lt;p&gt;Let’s start with a basic example. Imagine you’re working on a service, &lt;code&gt;MyService&lt;/code&gt;, that depends on an &lt;code&gt;IFoo&lt;/code&gt; interface. Nothing fancy, just your standard DI setup:&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;MyService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IFoo&lt;/span&gt; &lt;span class="n"&gt;_foo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Constructor with an injected service.&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;MyService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IFoo&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_foo&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// A method that prints a value.&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;PrintValue&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Get the value.&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetValue&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Print the value.&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;value&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;The &lt;code&gt;IFoo&lt;/code&gt; interface has a single method, &lt;code&gt;GetValue&lt;/code&gt;, which includes a default implementation. Here’s how the interface and its implementation look:&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;interface&lt;/span&gt; &lt;span class="nc"&gt;IFoo&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// A method declaration with a default implementation.&lt;/span&gt;
    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;GetValue&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"IFoo"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// An implementation of the interface.&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Foo&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IFoo&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Overriding the method.&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;GetValue&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"Foo"&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;When you run this in your trusty unit test, everything works as expected:&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;TestFixture&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;class&lt;/span&gt; &lt;span class="nc"&gt;FooTests&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Test&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;void&lt;/span&gt; &lt;span class="nf"&gt;GetValueMustReturnFoo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Create an instance of the service.&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Get the value.&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetValue&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Ensure the value is correct and equal to "Foo".&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AreEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Foo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;value&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;The test passes, confirming that &lt;code&gt;Foo.GetValue()&lt;/code&gt; returns &lt;code&gt;"Foo"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Finally, you use &lt;code&gt;MyService&lt;/code&gt; in a console app. In reality, this is a common scenario where the service would typically be resolved from a Dependency Injection (DI) container, but for simplicity, let's use the console app to demonstrate the concept.&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;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Create an instance of `Foo`.&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Create an instance of `MyService` using the `Foo` instance.&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;MyService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Execute the method to get an output.&lt;/span&gt;
        &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;PrintValue&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;Running this program produces the expected output:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;All is right in the world. Or so you think...&lt;/p&gt;

&lt;h2&gt;
  
  
  What Could Go Wrong?
&lt;/h2&gt;

&lt;p&gt;Now, imagine someone on your team decides to refactor the &lt;code&gt;Foo&lt;/code&gt; class by introducing a base class &lt;code&gt;FooBase&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="c1"&gt;// Introduce a base class.&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FooBase&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IFoo&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Derive `Foo` from the base class.&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Foo&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;FooBase&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// No other changes here.&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;GetValue&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"Foo"&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;Seems harmless enough, right? &lt;strong&gt;Right?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You run the tests. They pass. You deploy to production, and then… SURPRISE! The output changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IFoo
&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%2F2drugjl1o2q9q9xpdhu1.jpg" 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%2F2drugjl1o2q9q9xpdhu1.jpg" alt="One does not simply introduce a base class without consequences" width="651" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does This Happen?
&lt;/h2&gt;

&lt;p&gt;When a type is loaded into the CLR, a &lt;strong&gt;method table&lt;/strong&gt; is created and initialized. This table is used by the runtime to resolve method calls to the actual methods that will be executed. Think of it as a guide that tells the runtime which method to call based on the type and method signatures.&lt;/p&gt;

&lt;p&gt;Before the base class was introduced, the class &lt;code&gt;Foo&lt;/code&gt; directly implements the interface &lt;code&gt;IFoo&lt;/code&gt;. In this case, the method table for &lt;code&gt;Foo&lt;/code&gt; maps interface methods to the class’s implementation, as long as the method signatures match. So, when &lt;code&gt;GetValue()&lt;/code&gt; is called on an instance of &lt;code&gt;Foo&lt;/code&gt;, the runtime looks up the method in the &lt;code&gt;Foo&lt;/code&gt; class and resolves it to the &lt;code&gt;GetValue()&lt;/code&gt; method explicitly defined there.&lt;br&gt;
&lt;/p&gt;

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

+---------------+      +--------------+
| IFoo.GetValue | ---&amp;gt; | Foo.GetValue | 
+---------------+      +--------------+ 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, when you introduce a base class (&lt;code&gt;FooBase&lt;/code&gt;) and derive &lt;code&gt;Foo&lt;/code&gt; from it, things get interesting. Now, &lt;code&gt;Foo&lt;/code&gt; no longer &lt;strong&gt;directly&lt;/strong&gt; implements &lt;code&gt;IFoo&lt;/code&gt;. Instead, it inherits from &lt;code&gt;FooBase&lt;/code&gt;, which implements &lt;code&gt;IFoo&lt;/code&gt;. The method table is updated accordingly, and the runtime resolves method calls based on the inheritance chain. This means it looks at &lt;code&gt;FooBase&lt;/code&gt;'s method table to resolve the call. But here’s the kicker: &lt;code&gt;FooBase&lt;/code&gt; doesn’t implement &lt;code&gt;GetValue()&lt;/code&gt;, so the runtime falls back to the &lt;strong&gt;default interface implementation&lt;/strong&gt; from &lt;code&gt;IFoo&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

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

+---------------+      +--------------+
| IFoo.GetValue |      | Foo.GetValue | 
+---------------+      +--------------+ 
       ^  |            +------------------------------------+
       |  +----------&amp;gt; | FooBase.GetValue (not implemented) | 
       +--(default)--- +------------------------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In simpler terms, when &lt;code&gt;Foo&lt;/code&gt; inherits from &lt;code&gt;FooBase&lt;/code&gt;, the method table no longer directly points to &lt;code&gt;Foo.GetValue()&lt;/code&gt;. Since &lt;code&gt;Foo&lt;/code&gt; no longer explicitly implements &lt;code&gt;IFoo&lt;/code&gt;, the runtime defaults to the method in the interface, which might not be what you intended, leading to the unexpected &lt;code&gt;"IFoo"&lt;/code&gt; value instead of &lt;code&gt;"Foo"&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Prevent This?
&lt;/h2&gt;

&lt;p&gt;Don’t shoot yourself in the foot with Default Interface Implementations. Here’s how to use them wisely:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Understand the Behavior&lt;/strong&gt;: Default methods are convenient, but they can be tricky when paired with inheritance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoid Unnecessary Inheritance&lt;/strong&gt;: Inheritance is powerful, but don’t overuse it. If you need shared logic, &lt;a href="https://blog.ploeh.dk/2018/02/26/inheritance-composition-isomorphism/" rel="noopener noreferrer"&gt;prefer composition over inheritance&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Explicitly Derive from the Interface&lt;/strong&gt;: Even if you introduce a base class that implements an interface, the derived class should explicitly declare that it implements the interface itself and provide method overrides as necessary.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Explicitly implement the interface&lt;/span&gt;
&lt;span class="c1"&gt;// Yes, even if the class is derived from `FooBase`, which implements `IFoo`.&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Foo&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;FooBase&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IFoo&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Override the method.&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;GetValue&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"Foo"&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;ul&gt;
&lt;li&gt;
&lt;strong&gt;Test Through Interfaces&lt;/strong&gt;: Modify tests to interact with the interface directly, rather than through a concrete class or &lt;code&gt;var&lt;/code&gt;. This ensures that the behavior being tested aligns with the contract defined by the interface. Using &lt;code&gt;var&lt;/code&gt; or directly referencing the concrete class can inadvertently bypass interface behavior, masking potential issues with default implementations or inheritance.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// The improved test: Interact through the interface.&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Test&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;void&lt;/span&gt; &lt;span class="nf"&gt;GetValueMustReturnFoo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Create an instance of the service using the interface, not `var`.&lt;/span&gt;
    &lt;span class="n"&gt;IFoo&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Get the value.&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetValue&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Ensure the value is correct and equal to "Foo".&lt;/span&gt;
    &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AreEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Foo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;value&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;ul&gt;
&lt;li&gt;
&lt;strong&gt;Leverage Static Analysis Tools&lt;/strong&gt;: Use tools like Roslyn analyzers (e.g. &lt;a href="https://github.com/dotnet/roslyn-analyzers" rel="noopener noreferrer"&gt;Roslyn Analyzers for C#&lt;/a&gt; or &lt;a href="https://github.com/SonarSource/sonar-dotnet" rel="noopener noreferrer"&gt;SonarAnalyzer for .NET&lt;/a&gt;) to catch risky patterns.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Document and Review Changes&lt;/strong&gt;: Always document changes involving default methods and review them thoroughly.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Default Interface Implementations in C# are a double-edged sword. While they provide immense flexibility and streamline API evolution, they also introduce complexities that can catch even experienced developers off guard. As shown in this example, subtle changes in class hierarchies can lead to unexpected behaviors, often surfacing only in production.&lt;/p&gt;

&lt;p&gt;To avoid such pitfalls, prioritize composition over inheritance to reduce unintended coupling and improve code maintainability. Always test through interfaces to ensure that your implementations behave correctly, independent of specific class hierarchies. Additionally, document changes meticulously to keep the team aligned and prevent surprises.&lt;/p&gt;

&lt;p&gt;Default Interface Implementations may be powerful, but with a thoughtful approach, you can navigate their pitfalls and ensure that inheritance doesn’t troll you again.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
    </item>
    <item>
      <title>Lazy Dependency Injection for Microsoft DI ServiceProvider</title>
      <dc:creator>Aleksei Ananev</dc:creator>
      <pubDate>Sat, 30 Jan 2021 04:53:03 +0000</pubDate>
      <link>https://dev.to/hypercodeplace/lazy-dependency-injection-for-microsoft-di-serviceprovider-2149</link>
      <guid>https://dev.to/hypercodeplace/lazy-dependency-injection-for-microsoft-di-serviceprovider-2149</guid>
      <description>&lt;p&gt;Dependency Injection is a powerful tool and standard for achieving quality code. However, this can adversely affect performance and memory consumption, as instances may be created that are not used for the current request.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/hypercodeplace/lazy-dependency-injection-37en"&gt;The previous post&lt;/a&gt; detailed the problem and one solution that allows gracefully solving it without polluting your code. This solution is to use &lt;a href="https://github.com/servicetitan/lazy-proxy" rel="noopener noreferrer"&gt;LazyProxy&lt;/a&gt; for IoC containers. The main idea is to substitute an object of the real type with a proxy. This proxy is a runtime generated type that implemented a specific interface &lt;code&gt;T&lt;/code&gt; and called all members of this interface through &lt;code&gt;Lazy&amp;lt;T&amp;gt;&lt;/code&gt;. Thus, the behavior changes as if &lt;code&gt;Lazy&amp;lt;T&amp;gt;&lt;/code&gt; was injected instead of the &lt;code&gt;T&lt;/code&gt; interface. Instances are created only on demand, but at the same time, the code remains clean.&lt;/p&gt;

&lt;p&gt;Today I am happy to announce that &lt;code&gt;LazyProxy&lt;/code&gt; became available for one more container. &lt;a href="https://github.com/servicetitan/lazy-proxy-serviceprovider" rel="noopener noreferrer"&gt;LazyProxy.ServiceProvider&lt;/a&gt; library allows lazy dependency injection for &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.serviceprovider?view=dotnet-plat-ext-5.0" rel="noopener noreferrer"&gt;Microsoft's DI ServiceProvider&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Usage of this library is similar to already existing libraries &lt;a href="https://github.com/servicetitan/lazy-proxy-unity" rel="noopener noreferrer"&gt;LazyProxy.Unity&lt;/a&gt; and &lt;a href="https://github.com/servicetitan/lazy-proxy-autofac" rel="noopener noreferrer"&gt;LazyProxy.Autofac&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here is an example of how to use this library. Consider the following interface and implementation:&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;interface&lt;/span&gt; &lt;span class="nc"&gt;IFoo&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Bar&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IFoo&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Ctor"&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;void&lt;/span&gt; &lt;span class="nf"&gt;Bar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Bar"&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;A lazy registration for this service can be added like this:&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="c1"&gt;// Creating a service collection&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;services&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ServiceCollection&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Adding a lazy registration&lt;/span&gt;
&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddLazyScoped&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IMyService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MyService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Building the service provider&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;serviceProvider&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;BuildServiceProvider&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Consider the following usage of the registered service:&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;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Resolving the service..."&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;foo&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetService&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IFoo&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Executing the 'Bar' method..."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Bar&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Resolving the service...
Executing the 'Bar' method...
Ctor
Bar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see from the output, the constructor is not called until the first call to method &lt;code&gt;Bar&lt;/code&gt; is made.&lt;/p&gt;

&lt;p&gt;The initiative and brilliant initial implementation of the &lt;a href="https://github.com/servicetitan/lazy-proxy-serviceprovider" rel="noopener noreferrer"&gt;LazyProxy.ServiceProvider&lt;/a&gt; library belong entirely to &lt;a href="https://dev.to/cmendibl3"&gt;Carlos Mendible&lt;/a&gt;, for which I want to express gratitude and appreciation on behalf of the entire open-source community. Besides, Carlos has generously permitted to move the new repository alongside all other LazyProxy's repositories. That was a big step forward in the lazy dependency injection ideas.&lt;/p&gt;

&lt;h1&gt;
  
  
  GitHub Repositories
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://github.com/servicetitan/lazy-proxy" rel="noopener noreferrer"&gt;LazyProxy&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/servicetitan/lazy-proxy-autofac" rel="noopener noreferrer"&gt;LazyProxy.Autofac&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/servicetitan/lazy-proxy-unity" rel="noopener noreferrer"&gt;LazyProxy.Unity&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/servicetitan/lazy-proxy-serviceprovider" rel="noopener noreferrer"&gt;LazyProxy.ServiceProvider&lt;/a&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>ioc</category>
      <category>di</category>
      <category>lazy</category>
    </item>
    <item>
      <title>Lazy Dependency Injection for .NET</title>
      <dc:creator>Aleksei Ananev</dc:creator>
      <pubDate>Sat, 21 Nov 2020 01:54:57 +0000</pubDate>
      <link>https://dev.to/hypercodeplace/lazy-dependency-injection-37en</link>
      <guid>https://dev.to/hypercodeplace/lazy-dependency-injection-37en</guid>
      <description>&lt;h1&gt;
  
  
  Dependency Injection Problem
&lt;/h1&gt;

&lt;p&gt;Dependency injection is an essential part of modern applications that allows getting clean, reusable, testable code. Loosely coupled code and the single responsibility principle are considered best practices. And that's exactly what dependency injection helps to achieve.&lt;/p&gt;

&lt;p&gt;Along with the power and benefits of dependency injection, there is at least one problem that can be illustrated as follows.&lt;/p&gt;

&lt;p&gt;Assume a service called &lt;code&gt;MyService&lt;/code&gt; depends on &lt;code&gt;ServiceA&lt;/code&gt; and &lt;code&gt;ServiceB&lt;/code&gt;. The number of all nested dependencies is &lt;code&gt;N&lt;/code&gt; for &lt;code&gt;ServiceA&lt;/code&gt; and &lt;code&gt;M&lt;/code&gt; for &lt;code&gt;ServiceB&lt;/code&gt;:&lt;/p&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%2Fi%2F2moiqz0c17300691no5s.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%2Fi%2F2moiqz0c17300691no5s.png" alt="2" width="783" height="411"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;All these services are registered in an IoC container by corresponding interfaces:&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;container&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RegisterType&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IMyService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MyService&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;RegisterType&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IServiceA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ServiceA&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;RegisterType&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IServiceB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ServiceB&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;MyService&lt;/code&gt; service has the following implementation:&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;MyService&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IMyService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IServiceA&lt;/span&gt; &lt;span class="n"&gt;_serviceA&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IServiceB&lt;/span&gt; &lt;span class="n"&gt;_serviceB&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;MyService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IServiceA&lt;/span&gt; &lt;span class="n"&gt;serviceA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IServiceB&lt;/span&gt; &lt;span class="n"&gt;serviceB&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_serviceA&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serviceA&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;_serviceB&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serviceB&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;DoWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="k"&gt;value&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="k"&gt;value&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;42&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;_serviceA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DoWork&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;_serviceB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DoWork&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;DoWork&lt;/code&gt; method uses either &lt;code&gt;ServiceA&lt;/code&gt; or &lt;code&gt;ServiceB&lt;/code&gt; depending on the &lt;code&gt;value&lt;/code&gt; parameter. The important thing is that the method does not simultaneously use both services, but only one of them.&lt;/p&gt;

&lt;p&gt;Consider this example of using the &lt;code&gt;MyService&lt;/code&gt; service:&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;void&lt;/span&gt; &lt;span class="nf"&gt;MyMethod&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Using the container directly is for clarity only.&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Resolve&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IMyService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
    &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DoWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&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;In this case, only &lt;code&gt;ServiceA&lt;/code&gt; needs to be used. However, when resolving &lt;code&gt;MyService&lt;/code&gt; from the container, both &lt;code&gt;ServiceA&lt;/code&gt; and &lt;code&gt;ServiceB&lt;/code&gt; will be created as well as all other nested dependencies. Thus, instead of instantiating &lt;code&gt;(1 + N)&lt;/code&gt; services, all &lt;code&gt;(2 + N + M)&lt;/code&gt; are created.&lt;/p&gt;

&lt;p&gt;The following example illustrates another case where only part of the dependencies is used:&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;MyService&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IMyService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IServiceA&lt;/span&gt; &lt;span class="n"&gt;_serviceA&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IServiceB&lt;/span&gt; &lt;span class="n"&gt;_serviceB&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;MyService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IServiceA&lt;/span&gt; &lt;span class="n"&gt;serviceA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IServiceB&lt;/span&gt; &lt;span class="n"&gt;serviceB&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_serviceA&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serviceA&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;_serviceB&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serviceB&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;DoWorkA&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_serviceA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DoWork&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;DoWorkB&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_serviceB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DoWork&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;When calling the &lt;code&gt;DoWorkA&lt;/code&gt; method, only &lt;code&gt;ServiceA&lt;/code&gt; is used. &lt;code&gt;ServiceB&lt;/code&gt; is not needed in this case, but it was still created when the &lt;code&gt;MyService&lt;/code&gt; service resolving from the container:&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;void&lt;/span&gt; &lt;span class="nf"&gt;MyMethod&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Using the container directly is for clarity only.&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Resolve&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IMyService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
    &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DoWorkA&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;Of course, the examples given are too simple for real life and are given only for clarity. However, in practice, often, similar situations arise.&lt;/p&gt;

&lt;p&gt;To summarize, the problem with dependency injection is that it creates multiple instances that are not even used when the method is called. It leads to: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Increased consumption of CPU time to create unused service instances. Especially important if for some reason there are slow constructors in those services.&lt;/li&gt;
&lt;li&gt;Increased memory consumption due to allocation for unused service instances.&lt;/li&gt;
&lt;li&gt;Decreased performance due to increased load on the garbage collector.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Solutions
&lt;/h1&gt;

&lt;p&gt;This problem can be solved in several ways.&lt;/p&gt;

&lt;h3&gt;
  
  
  Singletons
&lt;/h3&gt;

&lt;p&gt;The specified problem becomes negligible if the services are registered in an IoC container as singletons. In this case, the problem only affects the first resolution of the service. However, in many cases, making all services singletons is a rather problematic task, especially for legacy code.&lt;/p&gt;

&lt;h3&gt;
  
  
  More Dependencies
&lt;/h3&gt;

&lt;p&gt;In some cases, the service can be divided into dependencies by reducing responsibility and methods. For instance, in the second example above, the &lt;code&gt;DoWorkA&lt;/code&gt; method and the &lt;code&gt;DoWorkB&lt;/code&gt; method could be divided into different services. But this approach may not always help, as can be seen from the first example above when the &lt;code&gt;DoWork&lt;/code&gt; method uses a condition by &lt;code&gt;value&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fewer Dependencies
&lt;/h3&gt;

&lt;p&gt;Sometimes, combining several services into one can reduce the depth of the dependency tree nesting. It is especially helpful when services are overly segregated. However, this can negatively impact code reusability and testability.&lt;/p&gt;

&lt;h3&gt;
  
  
  ServiceLocator
&lt;/h3&gt;

&lt;p&gt;Instead of injecting services, some use different service locators. However, this is considered to be an &lt;a href="https://blog.ploeh.dk/2015/10/26/service-locator-violates-encapsulation/" rel="noopener noreferrer"&gt;anti-pattern that breaks encapsulation&lt;/a&gt;, so ideally you want to avoid it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Inject Lazy&amp;lt;T&amp;gt; Instead of T
&lt;/h3&gt;

&lt;p&gt;Using &lt;code&gt;Lazy&amp;lt;T&amp;gt;&lt;/code&gt; rather than the &lt;code&gt;T&lt;/code&gt; solves the indicated problem.&lt;/p&gt;

&lt;p&gt;The implementation of the first example changes as follows:&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;MyService&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IMyService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;Lazy&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IServiceA&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_serviceA&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;Lazy&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IServiceB&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_serviceB&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;MyService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Lazy&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IServiceA&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;serviceA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Lazy&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IServiceB&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;serviceB&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_serviceA&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serviceA&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;_serviceB&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serviceB&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;DoWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="k"&gt;value&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="k"&gt;value&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;42&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;_serviceA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DoWork&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;_serviceB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DoWork&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, two &lt;code&gt;Lazy&amp;lt;T&amp;gt;&lt;/code&gt; instances are created when the &lt;code&gt;MyService&lt;/code&gt; service is resolved. &lt;code&gt;(1 + N)&lt;/code&gt; more services are resolved only when the &lt;code&gt;DoWork&lt;/code&gt; method is executed with the &lt;code&gt;value == 1&lt;/code&gt; (as in the example above). In total, instead of &lt;code&gt;(2 + N + M)&lt;/code&gt; created instances, only &lt;code&gt;(3 + N)&lt;/code&gt; are created.&lt;/p&gt;

&lt;p&gt;The difference is more significant, the more dependencies the &lt;code&gt;MyService&lt;/code&gt; service has, and method branches use the more specific services.&lt;/p&gt;

&lt;p&gt;The downside of this approach is that it pollutes the code with &lt;code&gt;Lazy&amp;lt;T&amp;gt;&lt;/code&gt; and &lt;code&gt;someServiceLazy.Value&lt;/code&gt; making it less readable.&lt;/p&gt;

&lt;h1&gt;
  
  
  LazyProxy
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://github.com/servicetitan/lazy-proxy" rel="noopener noreferrer"&gt;LazyProxy&lt;/a&gt; solves the above problem without requiring you to change your service code at all.&lt;/p&gt;

&lt;p&gt;This library allows you to generate at runtime a type that implements a given interface and proxies all members of this interface to calls through &lt;code&gt;Lazy&amp;lt;T&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The following example shows how &lt;code&gt;LazyProxy&lt;/code&gt; works.&lt;/p&gt;

&lt;p&gt;Assume there is the following interface:&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;interface&lt;/span&gt; &lt;span class="nc"&gt;IMyService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Foo&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;Then a lazy proxy type can be generated this way:&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="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;proxyType&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;LazyProxyBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetType&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IMyService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The generated type looks like this:&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="c1"&gt;// In reality, the implementation is a little more complicated,&lt;/span&gt;
&lt;span class="c1"&gt;// but the details are omitted for ease of understanding.&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LazyProxyImpl_IMyService&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IMyService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;Lazy&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IMyService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_service&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;LazyProxyImpl_IMyService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Lazy&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IMyService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_service&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Foo&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;The generated type hides all of the boilerplate code of using &lt;code&gt;Lazy&amp;lt;T&amp;gt;&lt;/code&gt;. So,  &lt;code&gt;LazyProxy&lt;/code&gt; can eliminate the main disadvantage of lazy injection but keep the main advantage.&lt;/p&gt;

&lt;h1&gt;
  
  
  LazyProxy Registration
&lt;/h1&gt;

&lt;p&gt;Generating a proxy type at runtime is only half the battle. It is necessary to register this type in the container somehow and preserve the ability to resolve a real type when calling &lt;code&gt;_service.Value&lt;/code&gt;. This can be achieved in several ways.&lt;/p&gt;

&lt;h3&gt;
  
  
  Named registrations
&lt;/h3&gt;

&lt;p&gt;Named registrations can be used to register and resolve a real service. This method can only be used for containers that support named registrations.&lt;/p&gt;

&lt;p&gt;Here is a simple example of how a proxy type and a real type can be registered in the &lt;code&gt;Autofac&lt;/code&gt; container:&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;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;registrationName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"RealService"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Creating a container builder.&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ContainerBuilder&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Registering a type mapping for the real service.&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;RegisterType&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MyService&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;Named&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IMyService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;registrationName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Registering a type mapping for the lazy proxy.&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="p"&gt;=&amp;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;context&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Resolve&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IComponentContext&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;LazyProxyBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateInstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;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;ResolveNamed&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IMyService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;registrationName&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;span class="n"&gt;As&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IMyService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Building the container.&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;container&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="nf"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Resolving the lazy proxy.&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;lazyProxy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Resolve&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IMyService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Marker interface
&lt;/h3&gt;

&lt;p&gt;Another way is generating an additional marker interface at runtime that will implement the main interface and be used to register and resolve a real service.&lt;/p&gt;

&lt;p&gt;This method is a little more complicated to implement than named registrations, as it requires a runtime code generation. Simultaneously, this method is universal, as it can work for containers that do not support named registrations.&lt;/p&gt;

&lt;h1&gt;
  
  
  LazyProxy for IoC Containers
&lt;/h1&gt;

&lt;p&gt;There are already ready-made libraries for some IoC containers that implement the described approach.&lt;/p&gt;

&lt;h3&gt;
  
  
  LazyProxy.Autofac
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/servicetitan/lazy-proxy-autofac" rel="noopener noreferrer"&gt;LazyProxy.Autofac&lt;/a&gt; implements lazy registrations for the &lt;code&gt;Autofac&lt;/code&gt; container.&lt;/p&gt;

&lt;p&gt;Here is an example of how to use this library:&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="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ContainerBuilder&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;RegisterLazy&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IFoo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;container&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="nf"&gt;Build&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;lazyProxy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Resolve&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IFoo&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  LazyProxy.Unity
&lt;/h3&gt;

&lt;p&gt;There is also an implementation for the &lt;code&gt;Unity&lt;/code&gt; container named &lt;a href="https://github.com/servicetitan/lazy-proxy-unity" rel="noopener noreferrer"&gt;LazyProxy.Unity&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The syntax is similar to the previous example:&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;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;UnityContainer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RegisterLazy&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IFoo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;lazyProxy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Resolve&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IFoo&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Dependency Injection is a powerful tool and standard for achieving quality code. However, it has the disadvantage that multiple instances are unnecessarily created. It negatively affects performance and memory consumption.&lt;/p&gt;

&lt;p&gt;There are several solutions that you should use whenever possible to mitigate the negative impact of dependency injection.&lt;/p&gt;

&lt;p&gt;One solution is using the &lt;code&gt;Lazy&amp;lt;T&amp;gt;&lt;/code&gt; injection instead of &lt;code&gt;T&lt;/code&gt;. However, such injection pollutes the code, so this use is not recommended.&lt;/p&gt;

&lt;p&gt;Instead, it is suggested to use the &lt;code&gt;LazyProxy&lt;/code&gt; library, which allows you to get lazy injection benefits while still getting clean code. This library can be used for various containers to register lazy dependencies. There are implementations for the &lt;code&gt;Unity&lt;/code&gt; and the &lt;code&gt;Autofac&lt;/code&gt; containers that allow you to simply register lazy dependencies.&lt;/p&gt;

&lt;h1&gt;
  
  
  GitHub Repositories
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/servicetitan/lazy-proxy" rel="noopener noreferrer"&gt;LazyProxy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/servicetitan/lazy-proxy-autofac" rel="noopener noreferrer"&gt;LazyProxy.Autofac&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/servicetitan/lazy-proxy-unity" rel="noopener noreferrer"&gt;LazyProxy.Unity&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>dotnet</category>
      <category>ioc</category>
      <category>di</category>
      <category>lazy</category>
    </item>
  </channel>
</rss>
