<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.2.0">Jekyll</generator><link href="https://mikolaj-kaminski.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://mikolaj-kaminski.com/" rel="alternate" type="text/html" /><updated>2023-02-19T15:07:27-06:00</updated><id>https://mikolaj-kaminski.com/feed.xml</id><title type="html">Mikołaj Kamiński</title><subtitle>My personal page and blog about software development
</subtitle><author><name>Mikołaj Kamiński</name><email>your-email@domain.com</email></author><entry><title type="html">How to test typed HTTP clients in .NET 6?</title><link href="https://mikolaj-kaminski.com/how-to-test-typed-http-client-with-di/" rel="alternate" type="text/html" title="How to test typed HTTP clients in .NET 6?" /><published>2022-07-03T06:00:00-05:00</published><updated>2022-07-03T06:00:00-05:00</updated><id>https://mikolaj-kaminski.com/how-to-test-typed-http-client-with-di</id><content type="html" xml:base="https://mikolaj-kaminski.com/how-to-test-typed-http-client-with-di/">&lt;p&gt;What is a typed HTTP client? In the simplest words, a strongly typed HTTP client is a class that has &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HttpClient&lt;/code&gt; dependency. Why do I prefer this solution over &lt;a href=&quot;https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-6.0#named-clients&quot;&gt;named HTTP clients&lt;/a&gt;?&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;You can easily inject the necessary dependencies into them.&lt;/li&gt;
  &lt;li&gt;There is no need to use strings as keys.&lt;/li&gt;
  &lt;li&gt;You may use IntelliSense while consuming them.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is an example of a client for which we will try to implement tests:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #b58900&quot;&gt;MyAwesomeHttpClient&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: #6c71c4&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;readonly&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;HttpClient&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;_httpClient&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #6c71c4&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;readonly&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;ISomeOtherDependency&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;_someOtherDependency&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;;&lt;/span&gt;

    &lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;MyAwesomeHttpClient&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;
        &lt;span style=&quot;color: #586e75&quot;&gt;HttpClient&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;httpClient&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt;
        &lt;span style=&quot;color: #586e75&quot;&gt;ISomeOtherDependency&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;someOtherDependency&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #586e75&quot;&gt;_httpClient&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;httpClient&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;;&lt;/span&gt;
        &lt;span style=&quot;color: #586e75&quot;&gt;_someOtherDependency&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;someOtherDependency&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;??&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;throw&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;ArgumentNullException&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #6c71c4&quot;&gt;nameof&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;someOtherDependency&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;));&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;async&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;Task&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #cb4b16&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;GetRandomDadJoke&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;()&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #cb4b16&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;request&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;HttpRequestMessage&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;HttpMethod&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Get&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;Uri&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;&quot;/&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;UriKind&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Relative&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;));&lt;/span&gt;
        &lt;span style=&quot;color: #cb4b16&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;response&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;await&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;_httpClient&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;SendAsync&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;request&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;);&lt;/span&gt;

        &lt;span style=&quot;color: #6c71c4&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;(!&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;response&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;IsSuccessStatusCode&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt;
            &lt;span style=&quot;color: #6c71c4&quot;&gt;throw&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;Exception&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;&quot;I can&apos;t haz dad joke...&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;);&lt;/span&gt;

        &lt;span style=&quot;color: #586e75&quot;&gt;_someOtherDependency&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;DoNothig&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;();&lt;/span&gt;
        &lt;span style=&quot;color: #cb4b16&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;joke&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;await&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;response&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Content&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;ReadAsStringAsync&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;();&lt;/span&gt;

        &lt;span style=&quot;color: #6c71c4&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;joke&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;how-to-register-and-configure-typed-http-client&quot;&gt;How to register and configure typed HTTP client?&lt;/h2&gt;

&lt;p&gt;To use typed HTTP clients, you must first register them in dependency injection container. Personally, I prefer to create a dedicated extension method, which I will then call on the service collection. Such an extension method has the advantage that I can register all the client’s dependencies and configure it in one place. Here is an example implementation:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;IServiceCollection&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;AddMyAwesomeHttpClient&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #6c71c4&quot;&gt;this&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;IServiceCollection&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;services&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: #586e75&quot;&gt;services&lt;/span&gt;
        &lt;span style=&quot;color: #657b83&quot;&gt;// Let&apos;s register our HTTP client&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;AddHttpClient&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;MyAwesomeHttpClient&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;()&lt;/span&gt;
        &lt;span style=&quot;color: #657b83&quot;&gt;// Then we need to configure it&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;ConfigureHttpClient&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;httpClient&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&amp;gt;&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
            &lt;span style=&quot;color: #586e75&quot;&gt;httpClient&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;BaseAddress&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;Uri&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;&quot;https://icanhazdadjoke.com&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;UriKind&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Absolute&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;);&lt;/span&gt;
            &lt;span style=&quot;color: #586e75&quot;&gt;httpClient&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;DefaultRequestHeaders&lt;/span&gt;
                &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Add&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #6c71c4&quot;&gt;nameof&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;HttpRequestHeader&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Accept&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;),&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;MediaTypeNames&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Text&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Plain&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;);&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;})&lt;/span&gt;
        &lt;span style=&quot;color: #657b83&quot;&gt;// Or maybe we want to add some exception policies to it?&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;AddPolicyHandler&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;HttpPolicyExtensions&lt;/span&gt;
            &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;HandleTransientHttpError&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;()&lt;/span&gt;
            &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;RetryAsync&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;retryCount&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;));&lt;/span&gt;
    
    &lt;span style=&quot;color: #657b83&quot;&gt;// Don&apos;t not forget about our client&apos;s dependencies!&lt;/span&gt;
    &lt;span style=&quot;color: #586e75&quot;&gt;services&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;TryAddTransient&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;ISomeOtherDependency&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;SomeOtherDependency&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;();&lt;/span&gt;

    &lt;span style=&quot;color: #6c71c4&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;services&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Let’s try to implement the tests.&lt;/p&gt;

&lt;h2 id=&quot;first-we-need-to-mock-the-httpclient&quot;&gt;First we need to mock the HttpClient&lt;/h2&gt;

&lt;p&gt;The core problem is mocking &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HttpClient&lt;/code&gt;, or rather &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HttpMessageHandler&lt;/code&gt;, which is used by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HttpClient&lt;/code&gt; injected to the typed HTTP client.&lt;/p&gt;

&lt;p&gt;For creating &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HttpMessageHandler&lt;/code&gt; mocks, I highly recommend the great &lt;a href=&quot;https://www.nuget.org/packages/RichardSzalay.MockHttp&quot;&gt;MockHttp&lt;/a&gt; library created by &lt;a href=&quot;https://github.com/richardszalay&quot;&gt;Richard Szalay&lt;/a&gt;. Take a look at this example:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #cb4b16&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;httpMessageHandlerMock&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;MockHttpMessageHandler&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;();&lt;/span&gt;
&lt;span style=&quot;color: #657b83&quot;&gt;// Mock the request&lt;/span&gt;
&lt;span style=&quot;color: #cb4b16&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;mockRequest&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;httpMessageHandlerMock&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;When&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;&quot;https://icanhazdadjoke.com/&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Respond&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;
            &lt;span style=&quot;color: #586e75&quot;&gt;MediaTypeNames&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Text&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Plain&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt;
            &lt;span style=&quot;color: #859900&quot;&gt;&quot;Why can&apos;t your nose be 12 inches long? Because then it&apos;d be a foot!&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;);&lt;/span&gt;
&lt;span style=&quot;color: #657b83&quot;&gt;// Create a mock HttpClient&lt;/span&gt;
&lt;span style=&quot;color: #cb4b16&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;httpClient&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;httpMessageHandlerMock&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;ToHttpClient&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;();&lt;/span&gt;

&lt;span style=&quot;color: #cb4b16&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;response&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;await&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;httpClient&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;GetStringAsync&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;&quot;https://icanhazdadjoke.com/&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;);&lt;/span&gt;
&lt;span style=&quot;color: #657b83&quot;&gt;// response: Why can&apos;t your nose be 12 inches long? Because then it&apos;d be a foot!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I think this tool is very useful.&lt;/p&gt;

&lt;h2 id=&quot;the-most-obvious-method-of-testing&quot;&gt;The most obvious method of testing&lt;/h2&gt;

&lt;p&gt;Take a look at this sample test:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Test&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;]&lt;/span&gt;
&lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;async&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;Task&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;MyAwesomeHttpClient_ShouldSucceed_WhenRequestingForRandomDadJoke&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;()&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: #6c71c4&quot;&gt;const&lt;/span&gt; &lt;span style=&quot;color: #cb4b16&quot;&gt;string&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;ValidJokeResponse&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt;
        &lt;span style=&quot;color: #859900&quot;&gt;&quot;My dog used to chase people on a bike a lot. It got so bad I had to take his bike away.&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #657b83&quot;&gt;// Create and configure HttpMessageHandler mock&lt;/span&gt;
    &lt;span style=&quot;color: #cb4b16&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;httpMessageHandlerMock&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;MockHttpMessageHandler&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;();&lt;/span&gt;
    &lt;span style=&quot;color: #586e75&quot;&gt;httpMessageHandlerMock&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;When&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;HttpMethod&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Get&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;&quot;https://icanhazdadjoke.com/&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Respond&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;MediaTypeNames&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Text&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Plain&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;ValidJokeResponse&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;);&lt;/span&gt;
    &lt;span style=&quot;color: #657b83&quot;&gt;// Create mock HttpClient out of HttpMessageHandler mock&lt;/span&gt;
    &lt;span style=&quot;color: #cb4b16&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;httpClientMock&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;httpMessageHandlerMock&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;ToHttpClient&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;();&lt;/span&gt;
    &lt;span style=&quot;color: #657b83&quot;&gt;// Configure it manually&lt;/span&gt;
    &lt;span style=&quot;color: #586e75&quot;&gt;httpClientMock&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;BaseAddress&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;Uri&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;&quot;https://icanhazdadjoke.com/&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;UriKind&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Absolute&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;);&lt;/span&gt;
    &lt;span style=&quot;color: #657b83&quot;&gt;// Create MyAwesomeHttpClient instance manually&lt;/span&gt;
    &lt;span style=&quot;color: #cb4b16&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;sut&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;MyAwesomeHttpClient&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;
        &lt;span style=&quot;color: #586e75&quot;&gt;httpClientMock&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt;
        &lt;span style=&quot;color: #586e75&quot;&gt;Mock&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Of&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;ISomeOtherDependency&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;());&lt;/span&gt;

    &lt;span style=&quot;color: #cb4b16&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;result&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;await&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;sut&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;GetRandomDadJoke&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;();&lt;/span&gt;

    &lt;span style=&quot;color: #586e75&quot;&gt;result&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Should&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;()&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Be&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;ValidJokeResponse&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;);&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I’m not happy with it. Actually, we inject not the same &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HttpClient&lt;/code&gt; that we configured with our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AddMyAwesomeHttpClient&lt;/code&gt; extension method. At first glance, we can see several problems:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;We need to manually inject dependencies into the typed client, instead of using a DI container for that.&lt;/li&gt;
  &lt;li&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HttpClient&lt;/code&gt; we are mocking is not configured by the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ConfigureHttpClient&lt;/code&gt; method. We need to configure it redundantly for the test purposes.&lt;/li&gt;
  &lt;li&gt;Mocked &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HttpClient&lt;/code&gt; is missing all exception policies we have configured.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It would definitely be best to test the HTTP client that we registered in the DI container with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AddMyAwesomeHttpClient&lt;/code&gt; method. Why? Because it is already properly configured and at the same time, we can test the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AddMyAwesomeHttpClient&lt;/code&gt; method.&lt;/p&gt;

&lt;h2 id=&quot;so-how-to-test-it-better&quot;&gt;So, how to test it better?&lt;/h2&gt;

&lt;p&gt;The main idea is to create a test DI container, register our client in it with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AddMyAwesomeHttpClient&lt;/code&gt; extension method, and then replace its primary &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HttpMessageHandler&lt;/code&gt; with mock.&lt;/p&gt;

&lt;p&gt;In order to achieve this, we need to create a helper class, which implements &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IHttpMessageHandlerBuilderFilter&lt;/code&gt; interface. Its task will be to replace the primary &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HttpMessageHandler&lt;/code&gt; of the tested &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HttpClient&lt;/code&gt; with mock. Let’s say we name this class &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TestHttpMessageHandlerBuilderFilter&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The second thing is that we want to be able to overwrite the handlers of multiple clients registered in the DI container at the same time. For this reason, we also need to implement some kind of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HttpMessageHandler&lt;/code&gt; mock registry that our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TestHttpMessageHandlerBuilderFilter&lt;/code&gt; will use. To simplify this issue, we can use our test DI container as a registry for the following entries:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #6c71c4&quot;&gt;internal&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;sealed&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #b58900&quot;&gt;HttpMessageHandlerMockWrapper&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;HttpMessageHandlerMockWrapper&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;
        &lt;span style=&quot;color: #586e75&quot;&gt;Type&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;typedHttpClientType&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt;
        &lt;span style=&quot;color: #586e75&quot;&gt;HttpMessageHandler&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;httpMessageHandlerMock&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #586e75&quot;&gt;TypedHttpClientType&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;typedHttpClientType&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;;&lt;/span&gt;
        &lt;span style=&quot;color: #586e75&quot;&gt;HttpMessageHandlerMock&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;httpMessageHandlerMock&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
    
    &lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;Type&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;TypedHttpClientType&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;;&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
    &lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;HttpMessageHandler&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;HttpMessageHandlerMock&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;;&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Our implementation of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IHttpMessageHandlerBuilderFilter&lt;/code&gt; will look like this:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #6c71c4&quot;&gt;internal&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;sealed&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #b58900&quot;&gt;TestHttpMessageHandlerBuilderFilter&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;IHttpMessageHandlerBuilderFilter&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: #6c71c4&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;readonly&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;IEnumerable&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;HttpMessageHandlerMockWrapper&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;_httpMessageHandlerWrappers&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;;&lt;/span&gt;

    &lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;TestHttpMessageHandlerBuilderFilter&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;
        &lt;span style=&quot;color: #657b83&quot;&gt;// Injection of previously registered maps&lt;/span&gt;
        &lt;span style=&quot;color: #586e75&quot;&gt;IEnumerable&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;HttpMessageHandlerMockWrapper&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;httpMessageHandlerWrappers&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt;

    &lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #586e75&quot;&gt;_httpMessageHandlerWrappers&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;httpMessageHandlerWrappers&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;Action&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;HttpMessageHandlerBuilder&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;Configure&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Action&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;HttpMessageHandlerBuilder&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #6c71c4&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;builder&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&amp;gt;&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
            &lt;span style=&quot;color: #657b83&quot;&gt;// Checking if a given HttpClient has a registered HttpMessageHandler mock&lt;/span&gt;
            &lt;span style=&quot;color: #cb4b16&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;mockHandlerWrapper&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;_httpMessageHandlerWrappers&lt;/span&gt;
                &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;SingleOrDefault&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;x&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&amp;gt;&lt;/span&gt;
                    &lt;span style=&quot;color: #586e75&quot;&gt;x&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;TypedHttpClientType&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Name&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Equals&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;
                        &lt;span style=&quot;color: #586e75&quot;&gt;builder&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Name&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt;
                        &lt;span style=&quot;color: #586e75&quot;&gt;StringComparison&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;InvariantCultureIgnoreCase&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;));&lt;/span&gt;

            &lt;span style=&quot;color: #6c71c4&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;mockHandlerWrapper&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;is&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;not&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt;
            &lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
                &lt;span style=&quot;color: #657b83&quot;&gt;// If so, the default handler is replaced with mock&lt;/span&gt;
                &lt;span style=&quot;color: #586e75&quot;&gt;Debug&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;WriteLine&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;$&quot;Overriding &lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color: #6c71c4&quot;&gt;nameof&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;builder&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;PrimaryHandler&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)}&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt; for &apos;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;builder&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Name&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;&apos; typed HTTP client&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;);&lt;/span&gt;
                &lt;span style=&quot;color: #586e75&quot;&gt;builder&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;PrimaryHandler&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;mockHandlerWrapper&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;HttpMessageHandlerMock&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;;&lt;/span&gt;
            &lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
            &lt;span style=&quot;color: #586e75&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;builder&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;);&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;};&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now we have to register everything in the test DI container. Let’s create an appropriate extension method for this purpose.&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #6c71c4&quot;&gt;internal&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #b58900&quot;&gt;DependencyInjectionExtensions&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;IServiceCollection&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;OverridePrimaryHttpMessageHandler&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;TClient&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;(&lt;/span&gt;
        &lt;span style=&quot;color: #6c71c4&quot;&gt;this&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;IServiceCollection&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;services&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt;
        &lt;span style=&quot;color: #586e75&quot;&gt;HttpMessageHandler&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;mockMessageHandler&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #6c71c4&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;services&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;==&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;throw&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;ArgumentNullException&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #6c71c4&quot;&gt;nameof&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;services&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;));&lt;/span&gt;
        &lt;span style=&quot;color: #6c71c4&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;mockMessageHandler&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;==&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;throw&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;ArgumentNullException&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #6c71c4&quot;&gt;nameof&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;mockMessageHandler&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;));&lt;/span&gt;

        &lt;span style=&quot;color: #657b83&quot;&gt;// Register a mock handler&lt;/span&gt;
        &lt;span style=&quot;color: #586e75&quot;&gt;services&lt;/span&gt;
            &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;AddTransient&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;_&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;HttpMessageHandlerMockWrapper&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #6c71c4&quot;&gt;typeof&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;TClient&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;),&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;mockMessageHandler&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;));&lt;/span&gt;

        &lt;span style=&quot;color: #657b83&quot;&gt;// Replace the default or already registered IHttpMessageHandlerBuilderFilter&lt;/span&gt;
        &lt;span style=&quot;color: #657b83&quot;&gt;// with our TestHttpMessageHandlerBuilderFilter&lt;/span&gt;
        &lt;span style=&quot;color: #586e75&quot;&gt;services&lt;/span&gt;
            &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Replace&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;
                &lt;span style=&quot;color: #586e75&quot;&gt;ServiceDescriptor&lt;/span&gt;
                    &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Transient&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;IHttpMessageHandlerBuilderFilter&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;TestHttpMessageHandlerBuilderFilter&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;());&lt;/span&gt;

        &lt;span style=&quot;color: #6c71c4&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;services&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;putting-it-all-together&quot;&gt;Putting it all together&lt;/h2&gt;

&lt;p&gt;Let’s try to write a test of our typed client that will use dependency injection and our mocking mechanism.&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Test&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;]&lt;/span&gt;
&lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;async&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;Task&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;MyAwesomeTypedHttpClient_ShouldSucceed_WhenRequestingForRandomDadJoke&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;()&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: #6c71c4&quot;&gt;const&lt;/span&gt; &lt;span style=&quot;color: #cb4b16&quot;&gt;string&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;ValidJokeResponse&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt;
        &lt;span style=&quot;color: #859900&quot;&gt;&quot;My dog used to chase people on a bike a lot. It got so bad I had to take his bike away.&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #657b83&quot;&gt;// Create and configure our HttpMessageHandler mock&lt;/span&gt;
    &lt;span style=&quot;color: #cb4b16&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;httpMessageHandlerMock&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;MockHttpMessageHandler&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;();&lt;/span&gt;
    &lt;span style=&quot;color: #586e75&quot;&gt;httpMessageHandlerMock&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;When&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;HttpMethod&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Get&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;&quot;https://icanhazdadjoke.com/&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Respond&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;MediaTypeNames&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Text&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Plain&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;ValidJokeResponse&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;);&lt;/span&gt;
    &lt;span style=&quot;color: #657b83&quot;&gt;// Create our test DI container&lt;/span&gt;
    &lt;span style=&quot;color: #cb4b16&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;serviceProvider&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;ServiceCollection&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;()&lt;/span&gt;
        &lt;span style=&quot;color: #657b83&quot;&gt;// Mock ISomeOtherDependency&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;AddTransient&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;_&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;Mock&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Of&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;ISomeOtherDependency&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;())&lt;/span&gt;
        &lt;span style=&quot;color: #657b83&quot;&gt;// Add and configure our typed HTTP client&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;AddMyAwesomeHttpClient&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;()&lt;/span&gt;
        &lt;span style=&quot;color: #657b83&quot;&gt;// Overwrite what you need&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;OverridePrimaryHttpMessageHandler&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;MyAwesomeHttpClient&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;httpMessageHandlerMock&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;BuildServiceProvider&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;();&lt;/span&gt;
    &lt;span style=&quot;color: #cb4b16&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;sut&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;serviceProvider&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;GetRequiredService&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;MyAwesomeHttpClient&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;();&lt;/span&gt;

    &lt;span style=&quot;color: #cb4b16&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;result&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;await&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;sut&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;GetRandomDadJoke&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;();&lt;/span&gt;

    &lt;span style=&quot;color: #586e75&quot;&gt;result&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Should&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;()&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Be&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;ValidJokeResponse&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;);&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It looks good and most importantly it works! We can even test our exception policy since we have fully configured HttpClient.&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;TestCase&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;HttpStatusCode&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;BadRequest&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)]&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;TestCase&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;HttpStatusCode&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;InternalServerError&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)]&lt;/span&gt;
&lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;async&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;Task&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;MyAwesomeTypedHttpClient_ShouldFail_WhenReceiveErrorResponseCode&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;
    &lt;span style=&quot;color: #586e75&quot;&gt;HttpStatusCode&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;httpStatusCode&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #cb4b16&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;failedRequestCountBeforeException&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: #cb4b16&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;httpMessageHandlerMock&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;MockHttpMessageHandler&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;();&lt;/span&gt;
    &lt;span style=&quot;color: #cb4b16&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;testHttpRequestDefinition&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;httpMessageHandlerMock&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;When&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;HttpMethod&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Get&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;&quot;https://icanhazdadjoke.com/&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Respond&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;httpStatusCode&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;);&lt;/span&gt;
    &lt;span style=&quot;color: #cb4b16&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;serviceProvider&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;ServiceCollection&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;()&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;AddTransient&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;_&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;Mock&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Of&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;ISomeOtherDependency&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;())&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;AddMyAwesomeHttpClient&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;()&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;OverridePrimaryHttpMessageHandler&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;MyAwesomeHttpClient&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;httpMessageHandlerMock&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;BuildServiceProvider&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;();&lt;/span&gt;
    &lt;span style=&quot;color: #cb4b16&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;sut&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;serviceProvider&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;GetRequiredService&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;MyAwesomeHttpClient&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;();&lt;/span&gt;

    &lt;span style=&quot;color: #cb4b16&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;action&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;async&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;await&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;sut&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;GetRandomDadJoke&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;();&lt;/span&gt;

    &lt;span style=&quot;color: #6c71c4&quot;&gt;await&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;action&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Should&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;()&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;ThrowAsync&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Exception&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;();&lt;/span&gt;
    &lt;span style=&quot;color: #586e75&quot;&gt;httpMessageHandlerMock&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;GetMatchCount&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;testHttpRequestDefinition&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Should&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Be&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;failedRequestCountBeforeException&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;);&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;Do you know a better way to test typed HTTP clients? Or maybe you have any questions or suggestions? If so, please don’t hesitate to contact me. I am curious what you think.&lt;/p&gt;

&lt;p&gt;I created &lt;a href=&quot;https://github.com/mikasjp/TestingTypedHttpClients&quot;&gt;a sample application&lt;/a&gt; that I published on GitHub. Enjoy!&lt;/p&gt;</content><author><name>Mikołaj Kamiński</name><email>your-email@domain.com</email></author><category term="dotnet" /><category term="tests" /><summary type="html">Strongly typed HTTP clients are very useful and convenient. Here&apos;s how to test them without sacrificing the advantages of dependency injection.</summary></entry><entry><title type="html">I couldn’t debug the code because of my name</title><link href="https://mikolaj-kaminski.com/jetbrains-rider-docker-compose-unicodedecodeerror-issue-fix/" rel="alternate" type="text/html" title="I couldn’t debug the code because of my name" /><published>2021-10-18T02:00:00-05:00</published><updated>2021-10-18T02:00:00-05:00</updated><id>https://mikolaj-kaminski.com/jetbrains-rider-docker-compose-unicodedecodeerror-issue-fix</id><content type="html" xml:base="https://mikolaj-kaminski.com/jetbrains-rider-docker-compose-unicodedecodeerror-issue-fix/">&lt;p&gt;Some time ago, I finally managed to switch from Visual Studio to JetBrains Rider at work. Finally, because I used to work a lot with Rider before, and I really like this IDE. Unfortunately, I ran into some annoying problems with docker-compose debug configuration.&lt;/p&gt;

&lt;p&gt;It turns out that the same problem also affects users of other InteliJ-based IDEs like RubyMine, PyCharm, PhpStorm and GoLand. Fortunately, I was able to fix it.&lt;/p&gt;

&lt;h2 id=&quot;debugging-docker-compose-service-and-unicodedecodeerror&quot;&gt;Debugging docker-compose service and UnicodeDecodeError&lt;/h2&gt;

&lt;p&gt;Rider solves the topic of Run/Debug configuration differently from Visual Studio, so I had to add my configuration myself. &lt;a href=&quot;https://blog.jetbrains.com/dotnet/2020/01/13/docker-compose-edit-continue-c-8-debugger-updates-rider-2019-3/&quot;&gt;It is not that hard&lt;/a&gt;. All you need to do is select the docker-compose file, select the service to which the debugger is to attach, and that’s it.&lt;/p&gt;

&lt;p&gt;What was my surprise when after clicking the Debug button I saw the following error:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Deploying &apos;Compose: local&apos;...
docker-compose -f C:\Repositories\TestProject\docker-compose.yml -f C:\Users\Mikołaj\AppData\Local\JetBrains\Rider2021.2\tmp\docker-compose.override.yml up --no-deps --build my_service
ERROR: .UnicodeDecodeError: &apos;utf-8&apos; codec can&apos;t decode byte 0xb3 in position 536: invalid start byte
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Have I made any mistake? I tried clicking the Run button. The application started without any problem. WTF?!&lt;/p&gt;

&lt;h2 id=&quot;mikołaj-is-a-name-of-doom&quot;&gt;Mikołaj is a name of doom&lt;/h2&gt;

&lt;p&gt;I decided to check the difference between the Rider launch process in Debug and Release mode. It turned out that in the case of the Debug  mode, it generates a docker-compose file with which it overwrites the original file. I was convinced that my original docker-compose was correct. Was the error related to the generated file? Let’s see what it looks like.
My temporary file was stored in the following location: 
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;%LocalAppData%\JetBrains\Rider2021.2\tmp\docker-compose.override.yml&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #268bd2&quot;&gt;version&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;3.4&quot;&lt;/span&gt;
&lt;span style=&quot;color: #268bd2&quot;&gt;services&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;:&lt;/span&gt;
  &lt;span style=&quot;color: #268bd2&quot;&gt;my_service&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;:&lt;/span&gt;
    &lt;span style=&quot;color: #268bd2&quot;&gt;entrypoint&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;:&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;/riderDebugger/runtime-dotnet.sh&quot;&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;/riderDebugger/JetBrains.Debugger.Worker.exe&quot;&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;--mode=server&quot;&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;--frontend-port=57001&quot;&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;--backend-port=57101&quot;&lt;/span&gt;
    &lt;span style=&quot;color: #268bd2&quot;&gt;environment&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;:&lt;/span&gt;
      &lt;span style=&quot;color: #268bd2&quot;&gt;RIDER_DEBUGGER_LOG_DIR&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;/riderLogs&quot;&lt;/span&gt;
      &lt;span style=&quot;color: #268bd2&quot;&gt;RESHARPER_LOG_CONF&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;/riderLogsConf/backend-log.xml&quot;&lt;/span&gt;
    &lt;span style=&quot;color: #268bd2&quot;&gt;ports&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;:&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;57001:57001&quot;&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;57101:57101&quot;&lt;/span&gt;
    &lt;span style=&quot;color: #268bd2&quot;&gt;volumes&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;:&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;C:&lt;/span&gt;&lt;span style=&quot;color: #d33682&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;Program&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;Files&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;(x86)&lt;/span&gt;&lt;span style=&quot;color: #d33682&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;JetBrains&lt;/span&gt;&lt;span style=&quot;color: #d33682&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;JetBrains&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;Rider&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;2021.1.1&lt;/span&gt;&lt;span style=&quot;color: #d33682&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;lib&lt;/span&gt;&lt;span style=&quot;color: #d33682&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;ReSharperHost:/riderDebugger&quot;&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;C:&lt;/span&gt;&lt;span style=&quot;color: #d33682&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;Users&lt;/span&gt;&lt;span style=&quot;color: #d33682&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;Miko�aj&lt;/span&gt;&lt;span style=&quot;color: #d33682&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;AppData&lt;/span&gt;&lt;span style=&quot;color: #d33682&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;Local&lt;/span&gt;&lt;span style=&quot;color: #d33682&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;JetBrains&lt;/span&gt;&lt;span style=&quot;color: #d33682&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;Rider2021.2&lt;/span&gt;&lt;span style=&quot;color: #d33682&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color: #d33682&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;DebuggerWorker&lt;/span&gt;&lt;span style=&quot;color: #d33682&quot;&gt;\\\
&lt;/span&gt;      &lt;span style=&quot;color: #859900&quot;&gt;JetBrains.Debugger.Worker.2021_10_17_20_32_30:/riderLogs:rw&quot;&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;C:&lt;/span&gt;&lt;span style=&quot;color: #d33682&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;Program&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;Files&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;(x86)&lt;/span&gt;&lt;span style=&quot;color: #d33682&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;JetBrains&lt;/span&gt;&lt;span style=&quot;color: #d33682&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;JetBrains&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;Rider&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;2021.1.1/bin:/riderLogsConf&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Take a look at the volumes section. One of the entries contains some strange character.&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;C:&lt;/span&gt;&lt;span style=&quot;color: #d33682&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;Users&lt;/span&gt;&lt;span style=&quot;color: #d33682&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;Miko�aj&lt;/span&gt;&lt;span style=&quot;color: #d33682&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;AppData&lt;/span&gt;&lt;span style=&quot;color: #d33682&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;Local&lt;/span&gt;&lt;span style=&quot;color: #d33682&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;JetBrains&lt;/span&gt;&lt;span style=&quot;color: #d33682&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;Rider2021.2&lt;/span&gt;&lt;span style=&quot;color: #d33682&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color: #d33682&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;DebuggerWorker&lt;/span&gt;&lt;span style=&quot;color: #d33682&quot;&gt;\\\
&lt;/span&gt;      &lt;span style=&quot;color: #859900&quot;&gt;JetBrains.Debugger.Worker.2021_10_17_20_32_30:/riderLogs:rw&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;My username contains a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;ł&quot;&lt;/code&gt; character and because of it, this file cannot be processed properly.&lt;/p&gt;

&lt;p&gt;But what can I do about it? After all, this file is generated automatically by Rider.&lt;/p&gt;

&lt;h2 id=&quot;lets-face-the-problem&quot;&gt;Let’s face the problem&lt;/h2&gt;

&lt;p&gt;When I found out that the bug was in the Rider itself, I &lt;a href=&quot;https://youtrack.jetbrains.com/issue/IDEA-264563&quot;&gt;reported it&lt;/a&gt; to technical support. I also found &lt;a href=&quot;https://youtrack.jetbrains.com/issue/PY-42620&quot;&gt;a similar report&lt;/a&gt; for PyCharm. Unfortunately, things haven’t moved forward since then. I decided to try to solve this problem myself. Fortunately, I was able to do this and can share my solution to this very annoying problem with others.&lt;/p&gt;

&lt;p&gt;The first idea was to change the username to one that does not contain Polish characters. It turned out that Windows does not rename the user’s folder when changing the username. Manually renaming the folder was not an option. This way I could corrupt my profile in the system.&lt;/p&gt;

&lt;p&gt;What if I changed the path where Rider stores temporary files? I started browsing the documentation from JetBrains and found &lt;a href=&quot;https://www.jetbrains.com/help/idea/2021.2/directories-used-by-the-ide-to-store-settings-caches-plugins-and-logs.html#change-ide-dirs&quot;&gt;an interesting article&lt;/a&gt; on advanced configuration of InteliJ-based IDEs. This article explains how you can change the paths that the IDE uses.&lt;/p&gt;

&lt;h2 id=&quot;solution&quot;&gt;Solution&lt;/h2&gt;

&lt;p&gt;Start your IDE, and go to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Help&lt;/code&gt; section in the main menu. There you will find the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Edit Custom Properties&lt;/code&gt; option. Click on it. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;%APPDATA%\JetBrains\{your_IDE_version}\idea.properties&lt;/code&gt; file will open for editing.&lt;/p&gt;

&lt;p&gt;Add the following line to it:&lt;/p&gt;

&lt;div class=&quot;language-properties highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #586e75&quot;&gt;idea.system.path&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;${root.dir}/JetBrains/Rider/system&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Save the file and restart the IDE. From now on, Rider will keep temporary files in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;C:\JetBrains\Rider\system&lt;/code&gt; directory. Of course you may have a different drive under the variable &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;${root.dir}&lt;/code&gt;, but the idea is the same.&lt;/p&gt;

&lt;p&gt;Finally, you have to clean up after yourself. Go to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Help&lt;/code&gt; section of the main menu and click &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Delete Leftover IDE Directories...&lt;/code&gt;. Rider will scan for unnecessary folders and offer to delete them.&lt;/p&gt;

&lt;p&gt;That’s all! Finally, you can start debugging your services launched from docker-compose!&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;From the moment the bug was reported to JetBrains support, 7 months passed until the publication of this post. I don’t know if they will ever fix this bug, but all I know is that it prevented me from working in my favorite IDE.&lt;/p&gt;

&lt;p&gt;I hope you found this article helpful. If you have any questions about this, feel free to contact me.&lt;/p&gt;</content><author><name>Mikołaj Kamiński</name><email>your-email@domain.com</email></author><category term="dotnet" /><category term="jetbrains" /><category term="rider" /><summary type="html">Some time ago, I finally managed to switch from Visual Studio to JetBrains Rider at work. Finally, because I used to work a lot with Rider before, and I really like this IDE. Unfortunately, I ran into some annoying problems with docker-compose debug configuration.</summary></entry><entry><title type="html">My favorite way to handle configuration in .NET Core</title><link href="https://mikolaj-kaminski.com/my-favorite-way-to-handle-configuration-dotnet-csharp/" rel="alternate" type="text/html" title="My favorite way to handle configuration in .NET Core" /><published>2021-04-23T10:30:00-05:00</published><updated>2021-04-23T10:30:00-05:00</updated><id>https://mikolaj-kaminski.com/my-favorite-way-to-handle-configuration-dotnet-csharp</id><content type="html" xml:base="https://mikolaj-kaminski.com/my-favorite-way-to-handle-configuration-dotnet-csharp/">&lt;p&gt;I am writing this blog post because I often see a configuration support proposal that uses hardcoded strings. Here’s a way to avoid it.&lt;/p&gt;

&lt;h2 id=&quot;my-way&quot;&gt;My way&lt;/h2&gt;

&lt;p&gt;This is a sample &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;appsettings.json&lt;/code&gt; file:&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;
    &lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;&quot;ExampleConfig&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;
        &lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;&quot;ValueA&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;&quot;aaa&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;
        &lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;&quot;ValueB&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;&quot;https://example.com&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;
        &lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;&quot;ValueC&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;1234&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;
    &lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is our example model which we want to load from the configuration:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #b58900&quot;&gt;ExampleConfig&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #cb4b16&quot;&gt;string&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;ValueA&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;;&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;set&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;;&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
    &lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;Uri&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;ValueB&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;;&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;set&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;;&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
    &lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #cb4b16&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;ValueC&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;;&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;set&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;;&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here’s how I read the model from the configuration:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #b58900&quot;&gt;ExampleCommandHandler&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: #6c71c4&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;readonly&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;IConfiguration&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;_configuration&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;;&lt;/span&gt;

    &lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;ExampleCommandHandler&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;IConfiguration&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;configuration&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #586e75&quot;&gt;_configuration&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;configuration&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;Task&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;Handle&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;ExampleCommand&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #cb4b16&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;exampleConfig&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;_configuration&lt;/span&gt;
            &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;GetSection&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #6c71c4&quot;&gt;nameof&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;ExampleConfig&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;))&lt;/span&gt;
            &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Get&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;ExampleConfig&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;()&lt;/span&gt;
            &lt;span style=&quot;color: #93a1a1&quot;&gt;??&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;throw&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;ConfigurationException&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #6c71c4&quot;&gt;nameof&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;ExampleConfig&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;));&lt;/span&gt;

        &lt;span style=&quot;color: #657b83&quot;&gt;// ...&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There is one thing you need to watch out for. To call the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Get&amp;lt;T&amp;gt;&lt;/code&gt; method, use &lt;a href=&quot;https://www.nuget.org/packages/Microsoft.Extensions.Configuration.Binder/&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Microsoft.Extensions.Configuration.Binder&lt;/code&gt;&lt;/a&gt; NuGet package.&lt;/p&gt;

&lt;p&gt;That’s it. No hardcoded strings in the code!&lt;/p&gt;</content><author><name>Mikołaj Kamiński</name><email>your-email@domain.com</email></author><category term="dotnet" /><category term="configuration" /><summary type="html">I am writing this blog post because I often see a configuration support proposal that uses hardcoded strings. Here’s a way to avoid it.</summary></entry><entry><title type="html">An elegant way to validate MediatR commands and queries</title><link href="https://mikolaj-kaminski.com/elegant-command-query-validation-mediatr-fluentvalidation/" rel="alternate" type="text/html" title="An elegant way to validate MediatR commands and queries" /><published>2021-04-22T06:00:00-05:00</published><updated>2021-04-22T06:00:00-05:00</updated><id>https://mikolaj-kaminski.com/elegant-command-query-validation-mediatr-fluentvalidation</id><content type="html" xml:base="https://mikolaj-kaminski.com/elegant-command-query-validation-mediatr-fluentvalidation/">&lt;p&gt;Today I would like to show you a really cool way to validate MediatR commands and queries using FluentValidation.&lt;/p&gt;

&lt;h2 id=&quot;the-ok-way&quot;&gt;The OK way&lt;/h2&gt;

&lt;p&gt;Fine. Each of us validates commands and queries in some way. After all, they are the input. The vast majority of the validation code I’ve seen so far has been integrated with command and query handlers.&lt;/p&gt;

&lt;p&gt;Here is an example handler code, which validates a command input.&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #b58900&quot;&gt;CreateUserCommandHandler&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;IRequestHandler&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;CreateUserCommand&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;async&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;Task&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Unit&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;Handle&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;
        &lt;span style=&quot;color: #586e75&quot;&gt;CreateUserCommand&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;request&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt;
        &lt;span style=&quot;color: #586e75&quot;&gt;CancellationToken&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;cancellationToken&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #657b83&quot;&gt;// Some command validation logic e.g.&lt;/span&gt;
        &lt;span style=&quot;color: #6c71c4&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cb4b16&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;IsNullOrEmpty&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;request&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Username&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;))&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
            &lt;span style=&quot;color: #6c71c4&quot;&gt;throw&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;ArgumentException&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;$&quot;Username cannot be empty&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;);&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;

        &lt;span style=&quot;color: #657b83&quot;&gt;// User creation logic&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There is nothing bad in that, but… What if we separate validation and command logic? Wouldn’t it be more maintainable?&lt;/p&gt;

&lt;h2 id=&quot;lets-separate-it&quot;&gt;Let’s separate it!&lt;/h2&gt;

&lt;p&gt;When I write about separation, I don’t mean extracting validation logic into a private method. It wouldn’t be a bit elegant. I’d like to extract all validation logic out of the handler. To achieve this, I am going to use the &lt;a href=&quot;https://fluentvalidation.net/&quot;&gt;FluentValidation&lt;/a&gt; library.&lt;/p&gt;

&lt;p&gt;Let’s implement our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CreateUserCommand&lt;/code&gt; validator.&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #b58900&quot;&gt;CreateUserCommandValidator&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;AbstractValidator&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;CreateUserCommand&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
  &lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;CustomerValidator&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: #586e75&quot;&gt;RuleFor&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;x&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;x&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Username&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;NotEmpty&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;()&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;WithMessage&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;&quot;Username cannot be empty&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;);&lt;/span&gt;
    &lt;span style=&quot;color: #586e75&quot;&gt;RuleFor&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;x&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;x&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Email&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;NotEmpty&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;()&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;WithMessage&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;&quot;Email address cannot be empty&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;);&lt;/span&gt;
    &lt;span style=&quot;color: #586e75&quot;&gt;RuleFor&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;x&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;x&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Email&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;EmailAddress&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;()&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;WithMessage&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;&quot;Please specify a valid email address&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;);&lt;/span&gt;
    &lt;span style=&quot;color: #657b83&quot;&gt;// ...&lt;/span&gt;
  &lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Of course, we have to register all our validators in the DI container. We can do it manually, but I recommend doing it using extensions from &lt;a href=&quot;https://docs.fluentvalidation.net/en/latest/aspnet.html&quot;&gt;the extra NuGet package&lt;/a&gt;. Alternatively you can do it using &lt;a href=&quot;/easy-di-container-services-registration-scrutor/&quot;&gt;Scrutor&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Then we have to modify our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CreateUserCommandHandler&lt;/code&gt; to use our brand new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CreateUserCommandValidator&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #b58900&quot;&gt;CreateUserCommandHandler&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;IRequestHandler&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;CreateUserCommand&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: #6c71c4&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;readonly&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;IValidator&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;CreateUserCommand&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;validator&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;;&lt;/span&gt;

    &lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;CreateUserCommandHandler&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;
        &lt;span style=&quot;color: #586e75&quot;&gt;IValidator&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;CreateUserCommand&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;validator&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #657b83&quot;&gt;// AbstractValidator implements IValidator interface&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #586e75&quot;&gt;_validator&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;validator&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;async&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;Task&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Unit&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;Handle&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;
        &lt;span style=&quot;color: #586e75&quot;&gt;CreateUserCommand&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;request&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt;
        &lt;span style=&quot;color: #586e75&quot;&gt;CancellationToken&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;cancellationToken&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #657b83&quot;&gt;// Our whole validation code becomes:&lt;/span&gt;
        &lt;span style=&quot;color: #586e75&quot;&gt;validator&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;ValidateAndThrow&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;request&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;);&lt;/span&gt;

        &lt;span style=&quot;color: #657b83&quot;&gt;// User creation logic&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Nice, but can we do it better? Well, of course we can.&lt;/p&gt;

&lt;h2 id=&quot;lets-call-our-validator-implicitly&quot;&gt;Let’s call our validator implicitly&lt;/h2&gt;

&lt;p&gt;The last improvement will be to completely remove the explicit validation from the handler. Now it should look like this:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #b58900&quot;&gt;CreateUserCommandHandler&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;IRequestHandler&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;CreateUserCommand&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;async&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;Task&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Unit&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;Handle&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;CreateUserCommand&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;request&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;CancellationToken&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;cancellationToken&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #657b83&quot;&gt;// User creation logic&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now I have to tell you something important about MediatR. It allows you to implement something like middlewares. It’s called &lt;a href=&quot;https://github.com/jbogard/MediatR/wiki/Behaviors&quot;&gt;pipeline behavior&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Behaviors allow you to build your own pipeline that will be executed before the handler. Let’s implement our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ValidationBehavior&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #b58900&quot;&gt;ValidationBehavior&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;TRequest&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;TResponse&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;IPipelineBehavior&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;TRequest&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;TResponse&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: #6c71c4&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;readonly&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;IValidator&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;TRequest&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;_validator&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;;&lt;/span&gt;

    &lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;ValidationBehavior&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;IValidator&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;TRequest&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;validator&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #586e75&quot;&gt;_validator&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;validator&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;Task&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;TResponse&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;Handle&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;
        &lt;span style=&quot;color: #586e75&quot;&gt;TRequest&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;request&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt;
        &lt;span style=&quot;color: #586e75&quot;&gt;CancellationToken&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;cancellationToken&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt;
        &lt;span style=&quot;color: #586e75&quot;&gt;RequestHandlerDelegate&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;TResponse&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #586e75&quot;&gt;_validator&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;ValidateAndThrow&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;request&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;);&lt;/span&gt; &lt;span style=&quot;color: #657b83&quot;&gt;// Check out the other methods for more advanced handling of validation errors &lt;/span&gt;
        &lt;span style=&quot;color: #6c71c4&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;();&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Finally, register it in a DI container. That’s it! Now, every time you run a command or query, it will be validated by the appropriate validator.&lt;/p&gt;

&lt;p&gt;Nothing prevents you from implementing more validators for one command/query, but it will require modification of our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ValidationBehavior&lt;/code&gt;. I’ll leave it for you as homework.&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;I hope you learned something interesting today. What do you think of this kind of separation? I think this makes the code easier to maintain.&lt;/p&gt;

&lt;p&gt;I also decided to write a small demo that you can find in &lt;a href=&quot;https://github.com/mikasjp/ValidationSeparation&quot;&gt;this GitHub repository&lt;/a&gt;. Enjoy!&lt;/p&gt;</content><author><name>Mikołaj Kamiński</name><email>your-email@domain.com</email></author><category term="dotnet" /><category term="cqrs" /><category term="validation" /><category term="mediatr" /><category term="fluentvalidation" /><summary type="html">Today I would like to show you a really cool way to validate MediatR commands and queries using FluentValidation.</summary></entry><entry><title type="html">Easy service registration in .NET DI containers using Scrutor</title><link href="https://mikolaj-kaminski.com/easy-di-container-services-registration-scrutor/" rel="alternate" type="text/html" title="Easy service registration in .NET DI containers using Scrutor" /><published>2021-04-21T06:00:00-05:00</published><updated>2021-04-21T06:00:00-05:00</updated><id>https://mikolaj-kaminski.com/easy-di-container-services-registration-scrutor</id><content type="html" xml:base="https://mikolaj-kaminski.com/easy-di-container-services-registration-scrutor/">&lt;p&gt;I like to make my life easier. If I can automate a process, I’d love to do it. It is no different in programming. Today I would like to show you how to automate dependency registration in DI container.&lt;/p&gt;

&lt;h2 id=&quot;manual-dependency-registration&quot;&gt;Manual dependency registration&lt;/h2&gt;

&lt;p&gt;For example, we have a set of dependencies to register:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;ConfigureServices&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;IServiceCollection&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;services&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: #586e75&quot;&gt;services&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;AddTransient&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;ICommandHandler&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;CreateUserCommand&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;,&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;CreateUserCommandHandler&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;()&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;AddTransient&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;ICommandHandler&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;DeleteUserCommand&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;,&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;DeleteUserCommandHandler&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;()&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;AddTransient&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;ICommandHandler&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;AddUserPostCommand&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;,&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;AddUserPostCommandHandler&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;()&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;AddTransient&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;IQueryHandler&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;GetUserQuery&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;User&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;,&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;GetUserQueryHandler&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;()&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;AddTransient&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;IQueryHandler&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;GetUserPostQuery&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;Post&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;,&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;GetUserPostQueryHandler&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;();&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It is not difficult to imagine a scenario where there will be many more dependencies to register. Luckily, there’s an easy way to automate this!&lt;/p&gt;

&lt;h2 id=&quot;automation-with-scrutor&quot;&gt;Automation with Scrutor&lt;/h2&gt;

&lt;p&gt;Let me introduce you to &lt;a href=&quot;https://github.com/khellang/Scrutor&quot;&gt;Scrutor&lt;/a&gt;. It is a small but powerful library that allows automatic assembly scanning and dependency registration. It is actually an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IServiceCollection&lt;/code&gt; extensions set.&lt;/p&gt;

&lt;p&gt;The following code does exactly the same as the previous example, except that it does it automatically.&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;ConfigureServices&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;IServiceCollection&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;services&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: #586e75&quot;&gt;services&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Scan&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;scan&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;scan&lt;/span&gt;
        &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;FromAssemblyOf&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;CreateUserCommand&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;()&lt;/span&gt; &lt;span style=&quot;color: #657b83&quot;&gt;// Indicates the assembly where all dependencies are located &lt;/span&gt;
            &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;AddClasses&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;classes&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;classes&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;AssignableTo&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #6c71c4&quot;&gt;typeof&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;ICommandHandler&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&amp;gt;)))&lt;/span&gt; &lt;span style=&quot;color: #657b83&quot;&gt;// Register all command handlers&lt;/span&gt;
                &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;AsImplementedInterfaces&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #657b83&quot;&gt;// We will be able to resolve them by their interfaces&lt;/span&gt;
                &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;WithTransientLifetime&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #657b83&quot;&gt;// Scope definition&lt;/span&gt;
            &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;AddClasses&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;classes&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;classes&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;AssignableTo&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #6c71c4&quot;&gt;typeof&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;IQueryHandler&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;,&amp;gt;)))&lt;/span&gt;
                &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;AsImplementedInterfaces&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;()&lt;/span&gt;
                &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;WithTransientLifetime&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;());&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now you won’t have to remember to register another dependency. Super handy, huh?&lt;/p&gt;

&lt;h2 id=&quot;concluding&quot;&gt;Concluding&lt;/h2&gt;

&lt;p&gt;In conclusion, it’s worth using Scrutor. Hope you find it useful and save you a lot of time. I encourage you to read its documentation and learn about its other capabilities.&lt;/p&gt;

&lt;p&gt;Do you automate any boring and repetitive stuff? Let me know!&lt;/p&gt;</content><author><name>Mikołaj Kamiński</name><email>your-email@domain.com</email></author><category term="dotnet" /><category term="di" /><summary type="html">I like to make my life easier. If I can automate a process, I’d love to do it. It is no different in programming. Today I would like to show you how to automate dependency registration in DI container.</summary></entry><entry><title type="html">Do we have to await every single C# async method?</title><link href="https://mikolaj-kaminski.com/do-we-have-to-await-every-single-async-method-c-sharp/" rel="alternate" type="text/html" title="Do we have to await every single C# async method?" /><published>2021-04-20T10:30:00-05:00</published><updated>2021-04-20T10:30:00-05:00</updated><id>https://mikolaj-kaminski.com/do-we-have-to-await-every-single-async-method-c-sharp</id><content type="html" xml:base="https://mikolaj-kaminski.com/do-we-have-to-await-every-single-async-method-c-sharp/">&lt;p&gt;Did you ever see code a like that? The method calls another asynchronous method and returns its direct result.&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;HttpPost&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;]&lt;/span&gt;
&lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;async&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;Task&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;GetUserQueryResult&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;Get&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;([&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;FromBody&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;GetUserQuery&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;query&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: #cb4b16&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;result&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;await&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;_mediatr&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Send&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;query&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;);&lt;/span&gt;
    &lt;span style=&quot;color: #6c71c4&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;result&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Okay, it works perfectly well, so what’s the matter? Now take a look at the code below:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;HttpPost&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;]&lt;/span&gt;
&lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;Task&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;GetUserQueryResult&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;Get&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;([&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;FromBody&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;GetUserQuery&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: #6c71c4&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;_mediatr&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Send&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;query&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;);&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I got rid of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;async&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;await&lt;/code&gt; keywords. This makes the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Get&lt;/code&gt; method synchronous. It just passes the task on and does not wait for the result.&lt;/p&gt;

&lt;p&gt;Both pieces of code work the same, but are they equally efficient? Let’s check it out!&lt;/p&gt;

&lt;h2 id=&quot;so-whats-the-difference&quot;&gt;So what’s the difference?&lt;/h2&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;await&lt;/code&gt; keyword is syntactic sugar. In fact, when compiled, it is turned into a state machine that manages the asynchronous code. Additional code increases execution time and consumes additional resources.&lt;/p&gt;

&lt;p&gt;Let me show you an example class:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #b58900&quot;&gt;TestClass&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;Task&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #cb4b16&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;MethodA&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;()&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #6c71c4&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;Task&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;FromResult&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;);&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;async&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;Task&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #cb4b16&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;MethodB&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;()&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #6c71c4&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;await&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;Task&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;FromResult&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;);&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And its benchmark:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #b58900&quot;&gt;Benchmark&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: #6c71c4&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;TestClass&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;testObject&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;TestClass&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;();&lt;/span&gt;

    &lt;span style=&quot;color: #93a1a1&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Benchmark&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;]&lt;/span&gt;
    &lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;async&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;Task&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;NoRedundantOperators&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;()&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #6c71c4&quot;&gt;await&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;testObject&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;MethodA&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;();&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #93a1a1&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Benchmark&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Baseline&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)]&lt;/span&gt;
    &lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;async&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;Task&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;RedundantOperators&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;()&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #6c71c4&quot;&gt;await&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;testObject&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;MethodB&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;();&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here are the results of the benchmark:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Method&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;Mean&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;Error&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;StdDev&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;Ratio&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;NoRedundantOperators&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;34.90 ns&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0.738 ns&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;1.035 ns&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0.58&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;RedundantOperators&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;60.17 ns&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;1.243 ns&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;2.144 ns&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;1.00&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;As you can see, the code without unnecessary operators is almost twice as fast!&lt;/p&gt;

&lt;p&gt;I have put all the benchmark code in my GitHub repository so you can test it yourself. You can find the repository &lt;a href=&quot;https://github.com/mikasjp/AsyncAwaitBenchmark&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;finally&quot;&gt;Finally&lt;/h2&gt;

&lt;p&gt;I hope I convince you that it is not always worth it to await every single async method call. As always, if you have any interesting thoughts on this topic, please let me know!&lt;/p&gt;</content><author><name>Mikołaj Kamiński</name><email>your-email@domain.com</email></author><category term="csharp" /><category term="async" /><summary type="html">Do we have to await each C# async method? Does this have any effect on code performance? Let&apos;s check it out!</summary></entry><entry><title type="html">How to merge JSON documents in .NET Core and .NET 5?</title><link href="https://mikolaj-kaminski.com/how-to-merge-json-net-csharp/" rel="alternate" type="text/html" title="How to merge JSON documents in .NET Core and .NET 5?" /><published>2021-04-19T10:30:00-05:00</published><updated>2021-04-19T10:30:00-05:00</updated><id>https://mikolaj-kaminski.com/how-to-merge-json-net-csharp</id><content type="html" xml:base="https://mikolaj-kaminski.com/how-to-merge-json-net-csharp/">&lt;p&gt;Let’s say we have two JSON documents that we would like to merge. How can this be achieved?&lt;/p&gt;

&lt;h2 id=&quot;using-newtonsoftjson&quot;&gt;Using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Newtonsoft.Json&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;In .NET Core, until version 3 was released, the default serializer was the well-known and liked &lt;a href=&quot;https://www.nuget.org/packages/Newtonsoft.Json/&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Newtonsoft.Json&lt;/code&gt;&lt;/a&gt;. Merging JSON documents with this library is very simple:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #cb4b16&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;object_A&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;JObject&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Parse&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;&quot;{ &apos;A&apos;: 1, &apos;B&apos;: 2, &apos;C&apos;: 3 }&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;);&lt;/span&gt;
&lt;span style=&quot;color: #cb4b16&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;object_B&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;JObject&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Parse&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;&quot;{ &apos;C&apos;: 4, &apos;D&apos;: 5, &apos;E&apos;: 6 }&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;);&lt;/span&gt;

&lt;span style=&quot;color: #cb4b16&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;object_C&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;JObject&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;();&lt;/span&gt;
&lt;span style=&quot;color: #586e75&quot;&gt;object_C&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Merge&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;object_A&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;);&lt;/span&gt;
&lt;span style=&quot;color: #586e75&quot;&gt;object_C&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Merge&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;object_B&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;);&lt;/span&gt;
&lt;span style=&quot;color: #657b83&quot;&gt;/*
object_C is:
{
  &quot;A&quot;: 1,
  &quot;B&quot;: 2,
  &quot;C&quot;: 4,
  &quot;D&quot;: 5,
  &quot;E&quot;: 6
}
*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;here-comes-systemtextjson&quot;&gt;Here comes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;System.Text.Json&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;System.Text.Json&lt;/code&gt; was released with the release of .NET Core 3, and it is part of its runtime. However, it can be used with earlier versions of .NET Core by installing the appropriate &lt;a href=&quot;https://www.nuget.org/packages/System.Text.Json&quot;&gt;NuGet package&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So, how to merge JSON documents with a brand new, blazing fast library released by Microsoft? It turns out that at the time of writing this post, there is no user-friendly API implemented yet.&lt;/p&gt;

&lt;p&gt;Does that mean it is impossible? Definitely not. While looking for a way to solve this problem, I came across &lt;a href=&quot;https://docs.microsoft.com/pl-pl/dotnet/standard/serialization/system-text-json-migrate-from-newtonsoft-how-to?pivots=dotnet-5-0#jsondocument-is-read-only&quot;&gt;an article&lt;/a&gt; on the Microsoft website that described the differences between &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;System.Text.Json&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Newtonsoft.Json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For performance reasons, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JsonDocument&lt;/code&gt; object is read-only as opposed to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JObject&lt;/code&gt;. This is the reason why Microsoft has not implemented the document merge API. Fortunately, there is an API suggestion that is covered in &lt;a href=&quot;https://github.com/dotnet/runtime/issues/31433&quot;&gt;this GitHub issue&lt;/a&gt;. It seems that the proposed API is faster than the API of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Newtonsoft.Json&lt;/code&gt; library.&lt;/p&gt;

&lt;p&gt;Here is a BenchmarkDotNet comparison results of both APIs:&lt;/p&gt;

&lt;table class=&quot;table-overflow&quot;&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Method&lt;/th&gt;
      &lt;th&gt;Mean&lt;/th&gt;
      &lt;th&gt;Error&lt;/th&gt;
      &lt;th&gt;StdDev&lt;/th&gt;
      &lt;th&gt;Median&lt;/th&gt;
      &lt;th&gt;Min&lt;/th&gt;
      &lt;th&gt;Max&lt;/th&gt;
      &lt;th&gt;Ratio&lt;/th&gt;
      &lt;th&gt;Gen 0&lt;/th&gt;
      &lt;th&gt;Gen 1&lt;/th&gt;
      &lt;th&gt;Gen 2&lt;/th&gt;
      &lt;th&gt;Allocated&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;MergeNewtonsoft&lt;/td&gt;
      &lt;td&gt;29.01 us&lt;/td&gt;
      &lt;td&gt;0.570 us&lt;/td&gt;
      &lt;td&gt;0.656 us&lt;/td&gt;
      &lt;td&gt;28.84 us&lt;/td&gt;
      &lt;td&gt;28.13 us&lt;/td&gt;
      &lt;td&gt;30.19 us&lt;/td&gt;
      &lt;td&gt;1.00&lt;/td&gt;
      &lt;td&gt;7.0801&lt;/td&gt;
      &lt;td&gt;0.0610&lt;/td&gt;
      &lt;td&gt;-&lt;/td&gt;
      &lt;td&gt;28.98 KB&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Merge_New&lt;/td&gt;
      &lt;td&gt;16.41 us&lt;/td&gt;
      &lt;td&gt;0.293 us&lt;/td&gt;
      &lt;td&gt;0.274 us&lt;/td&gt;
      &lt;td&gt;16.41 us&lt;/td&gt;
      &lt;td&gt;16.02 us&lt;/td&gt;
      &lt;td&gt;17.00 us&lt;/td&gt;
      &lt;td&gt;0.57&lt;/td&gt;
      &lt;td&gt;1.7090&lt;/td&gt;
      &lt;td&gt;-&lt;/td&gt;
      &lt;td&gt;-&lt;/td&gt;
      &lt;td&gt;6.99 KB&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;final-thoughts&quot;&gt;Final thoughts&lt;/h2&gt;

&lt;p&gt;It looks like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;System.Text.Json&lt;/code&gt; will stay with us longer. I wonder if it will get an official API implementation for merging JSON documents. What do you think? If you have any interesting thoughts on this topic please let me know!&lt;/p&gt;</content><author><name>Mikołaj Kamiński</name><email>your-email@domain.com</email></author><category term="dotnet" /><category term="json" /><category term="serialization" /><category term="5days5blogposts" /><summary type="html">Let’s say we have two JSON documents that we would like to merge. How can this be achieved using Newtonsoft.Json and System.Text.Json libraries?</summary></entry><entry><title type="html">ASP.NET Core, Newtonsoft JSON serializer and DateTime handling issue</title><link href="https://mikolaj-kaminski.com/newtonsoft-datetime-deserialization-issue-c-sharp/" rel="alternate" type="text/html" title="ASP.NET Core, Newtonsoft JSON serializer and DateTime handling issue" /><published>2021-04-14T01:30:00-05:00</published><updated>2021-04-14T01:30:00-05:00</updated><id>https://mikolaj-kaminski.com/newtonsoft-datetime-deserialization-issue-c-sharp</id><content type="html" xml:base="https://mikolaj-kaminski.com/newtonsoft-datetime-deserialization-issue-c-sharp/">&lt;p&gt;Today I encountered an interesting case. I got a report that “something changes the date format while processing data”. I started debugging our distributed system looking for the source of the problem. It took me a while, so I’d like to share this story today, so you don’t have to waste your time.&lt;/p&gt;

&lt;h2 id=&quot;dynamic-properties-in-a-statically-typed-world&quot;&gt;Dynamic properties in a statically typed world&lt;/h2&gt;

&lt;p&gt;One of the microservices handles the HTTP POST request which the body model is similar to this:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #b58900&quot;&gt;ExampleModel&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: #657b83&quot;&gt;// ...&lt;/span&gt;
    &lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;JObject&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;DynamicObject&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;;&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;set&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;;&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;For simplicity let’s say that exactly that request model is stored in NoSQL database and could be retrieved with another endpoint.&lt;/p&gt;

&lt;p&gt;Another service calls our application with a following HTTP request body:&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;
    &lt;/span&gt;&lt;span style=&quot;color: #002b36;background-color: #dc322f&quot;&gt;//&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #002b36;background-color: #dc322f&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;
    &lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;&quot;dynamicObject&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;
        &lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;&quot;someStringProperty&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;&quot;2021-04-14T08:30:00.000+0000&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;
        &lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;&quot;anotherStringProperty&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;&quot;QWERTY&quot;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;
    &lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then requests it back and gets following response:&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;
    &lt;/span&gt;&lt;span style=&quot;color: #002b36;background-color: #dc322f&quot;&gt;//&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #002b36;background-color: #dc322f&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;
    &lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;&quot;dynamicObject&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;
        &lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;&quot;someStringProperty&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;&quot;2021-04-14T08:30:00Z&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #002b36;background-color: #dc322f&quot;&gt;//&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #002b36;background-color: #dc322f&quot;&gt;wtf?!&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;
        &lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;&quot;anotherStringProperty&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;&quot;QWERTY&quot;&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;
    &lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As you can see, the value of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;someStringProperty&lt;/code&gt; is different from what was sent before! In my case, this is unacceptable behavior. I need it to be exactly the same string.&lt;/p&gt;

&lt;h2 id=&quot;solution&quot;&gt;Solution&lt;/h2&gt;

&lt;p&gt;After a while of debugging I found a culprit. Newtonsoft JSON serializer parsed &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;someStringProperty&lt;/code&gt; as a date. However, client service treats it as string. It turns out that this is default Newtonsoft JSON serializer behavior. It just guessed the type based on the value.&lt;/p&gt;

&lt;p&gt;The solution is to create serializer with the following &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JsonSerializerSettings&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #6c71c4&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;JsonSerializerSettings&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;()&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: #657b83&quot;&gt;// by default it is DateParseHandling.DateTime&lt;/span&gt;
    &lt;span style=&quot;color: #586e75&quot;&gt;DateParseHandling&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;DateParseHandling&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;None&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;someStringProperty&lt;/code&gt; will be parsed as a string. Fixed!&lt;/p&gt;

&lt;h2 id=&quot;one-more-thing&quot;&gt;One more thing&lt;/h2&gt;

&lt;p&gt;While searching the internet for a solution to my problem, I came across an interesting open GitHub issue in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Newtonsoft.Json&lt;/code&gt; library repository. It is closely related to my problem. At the time of writing this post, it’s still open for &lt;strong&gt;almost 5 years&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;Take a look: &lt;a href=&quot;https://github.com/JamesNK/Newtonsoft.Json/issues/904&quot;&gt;“A string that looks like a date is changed when deserializing an ISerializable object #904”&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;Hopefully, writing this post will save someone from a long debugging session. If you have any interesting thoughts on this, or I helped you somehow, please let me know. I will be very pleased!&lt;/p&gt;</content><author><name>Mikołaj Kamiński</name><email>your-email@domain.com</email></author><category term="csharp" /><category term="serialization" /><summary type="html">Today I encountered an interesting case. I got a report that “something changes the date format while processing data”. I started debugging our distributed system looking for the source of the problem. It took me a while, so I’d like to share this story today, so you don’t have to waste your time.</summary></entry><entry><title type="html">Extension methods in C# and Ruby</title><link href="https://mikolaj-kaminski.com/extension-methods-in-ruby-and-c-sharp/" rel="alternate" type="text/html" title="Extension methods in C# and Ruby" /><published>2021-04-12T01:00:00-05:00</published><updated>2021-04-12T01:00:00-05:00</updated><id>https://mikolaj-kaminski.com/extension-methods-in-ruby-and-c-sharp</id><content type="html" xml:base="https://mikolaj-kaminski.com/extension-methods-in-ruby-and-c-sharp/">&lt;p&gt;Extending classes with new methods is a pretty useful feature of object-oriented programming languages. However, implementation of extension methods can be more or less simple and elegant. Today I would like to compare implementation of extension methods in C# and Ruby.&lt;/p&gt;

&lt;h2 id=&quot;c-extension-methods&quot;&gt;C# extension methods&lt;/h2&gt;

&lt;p&gt;Let’s consider the following example class.&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #b58900&quot;&gt;ExampleClass&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #cb4b16&quot;&gt;string&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;GetName&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;()&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #6c71c4&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;&quot;Mikołaj&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To extend it with a new method we have to implement another independent static class, which has an implementation of our extension method.&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #b58900&quot;&gt;ExampleClassExtensions&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: #6c71c4&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: #cb4b16&quot;&gt;string&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;Greet&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #6c71c4&quot;&gt;this&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;ExampleClass&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;exampleClass&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #cb4b16&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;name&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;exampleClass&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;GetName&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;();&lt;/span&gt;
        &lt;span style=&quot;color: #6c71c4&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;$&quot;Hello &lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;!&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There are two important things. The first parameter of the extension method have to be preceded by the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;this&lt;/code&gt; keyword and should be of the type on which the method is operating.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ExampleClassExtensions&lt;/code&gt; can be named anything you like. It may also contain extension methods for classes other than &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ExampleClass&lt;/code&gt;. I named it so as to keep a clear naming convention.&lt;/p&gt;

&lt;h2 id=&quot;the-ruby-way&quot;&gt;The Ruby way&lt;/h2&gt;

&lt;p&gt;Okay, so let’s start with our example class which will be extended with extra method.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #6c71c4&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #b58900&quot;&gt;ExampleClass&lt;/span&gt;
    &lt;span style=&quot;color: #6c71c4&quot;&gt;def&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;get_name&lt;/span&gt;
        &lt;span style=&quot;color: #859900&quot;&gt;&quot;Mikołaj&quot;&lt;/span&gt;
    &lt;span style=&quot;color: #6c71c4&quot;&gt;end&lt;/span&gt;
&lt;span style=&quot;color: #6c71c4&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Implementation of an extension method is as simple as redefining our ExampleClass with an extra method. Take a look:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #6c71c4&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #b58900&quot;&gt;ExampleClass&lt;/span&gt;
    &lt;span style=&quot;color: #6c71c4&quot;&gt;def&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;greet&lt;/span&gt;
        &lt;span style=&quot;color: #859900&quot;&gt;&quot;Hello &lt;/span&gt;&lt;span style=&quot;color: #d33682&quot;&gt;#{&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;get_name&lt;/span&gt;&lt;span style=&quot;color: #d33682&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;!&quot;&lt;/span&gt;
    &lt;span style=&quot;color: #6c71c4&quot;&gt;end&lt;/span&gt;
&lt;span style=&quot;color: #6c71c4&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That’s it. Super simple.&lt;/p&gt;

&lt;h2 id=&quot;which-one-i-consider-to-be-better&quot;&gt;Which one I consider to be better?&lt;/h2&gt;

&lt;p&gt;I really like simple solutions, so at first glance Ruby extension methods implementation seems better to me.&lt;/p&gt;

&lt;p&gt;On the other hand, the C# solution does not directly modify the class being extended. The notation is more complicated, but it provides a separation between the class and its extensions.&lt;/p&gt;

&lt;p&gt;It’s hard for me to decide which solution is better. I’m just getting started with Ruby, and I have plans to study its object model better. I think it is too early to express my opinion on this.&lt;/p&gt;

&lt;p&gt;If you have any interesting thoughts on this topic, please let me know!&lt;/p&gt;</content><author><name>Mikołaj Kamiński</name><email>your-email@domain.com</email></author><category term="thoughts" /><category term="ruby" /><category term="csharp" /><summary type="html">Extending classes with new methods is a pretty useful feature of object-oriented programming languages. However, implementation of extension methods can be more or less simple and elegant. Today I would like to compare implementation of extension methods in C# and Ruby.</summary></entry><entry><title type="html">Why do I find Ruby sexy?</title><link href="https://mikolaj-kaminski.com/why-ruby-is-sexy/" rel="alternate" type="text/html" title="Why do I find Ruby sexy?" /><published>2021-04-10T06:00:00-05:00</published><updated>2021-04-10T06:00:00-05:00</updated><id>https://mikolaj-kaminski.com/why-ruby-is-sexy</id><content type="html" xml:base="https://mikolaj-kaminski.com/why-ruby-is-sexy/">&lt;p&gt;I am a full time .NET developer, but I have been interested in Ruby for some time. Not very professional, but I liked this technology very much. I would like to share why I think so.&lt;/p&gt;

&lt;figure style=&quot;border: 1px solid #ddd; padding: 1em 1em 0 1em; border-radius:5px; width: max-content; margin-left: auto; margin-right: auto; max-width: 100%;&quot;&gt;&lt;img class=&quot;image&quot; src=&quot;/assets/2021-04/2021-04-10-why-ruby-is-sexy/meme.png&quot; style=&quot;max-width:100%; margin:auto; padding-bottom: 1em;&quot; loading=&quot;lazy&quot; /&gt;&lt;/figure&gt;

&lt;h2 id=&quot;human-friendly-syntax&quot;&gt;Human friendly syntax&lt;/h2&gt;

&lt;p&gt;Ruby’s creator, Yukihiro Matsumoto, said in one of the interviews: “Ruby is designed for humans, not machines”. I think that he managed to achieve his goal.&lt;/p&gt;

&lt;p&gt;Ruby has very clean and simple syntax which makes it human friendly. I like when code is easy to read and understand.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #6c71c4&quot;&gt;def&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;say_hello&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;name&lt;/span&gt;
    &lt;span style=&quot;color: #859900&quot;&gt;&quot;Hello &lt;/span&gt;&lt;span style=&quot;color: #d33682&quot;&gt;#{&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #d33682&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;!&quot;&lt;/span&gt;
&lt;span style=&quot;color: #6c71c4&quot;&gt;end&lt;/span&gt;

&lt;span style=&quot;color: #93a1a1&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;&quot;Mikołaj&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;&quot;Tom&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;&quot;Jerry&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;]&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;map&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;x&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;|&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;say_hello&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;x&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;each&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;x&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;|&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;puts&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;x&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;At first, it may look a bit like Python syntax, but unlike it, Ruby doesn’t force indentation. I believe that this is a great advantage over Python.&lt;/p&gt;

&lt;p&gt;I’ve heard that code written in Ruby is so readable that programmers use it to discuss business logic with non-technical people. Pretty cool!&lt;/p&gt;

&lt;h2 id=&quot;rich-standard-library&quot;&gt;Rich standard library&lt;/h2&gt;

&lt;p&gt;The Ruby Standard Library is so rich that I can’t cover all the cool features in this post.
It’s great how many useful tools we get out of the box.&lt;/p&gt;

&lt;p&gt;Let me show you some date and time examples.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #b58900&quot;&gt;Time&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;now&lt;/span&gt;                &lt;span style=&quot;color: #657b83&quot;&gt;# produces current date and time&lt;/span&gt;
&lt;span style=&quot;color: #b58900&quot;&gt;Time&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;now&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;utc&lt;/span&gt;            &lt;span style=&quot;color: #657b83&quot;&gt;# produces current date and time converted to UTC&lt;/span&gt;
&lt;span style=&quot;color: #b58900&quot;&gt;Time&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;&quot;2021-06-01&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt;  &lt;span style=&quot;color: #657b83&quot;&gt;# produces new Time object which stores given date&lt;/span&gt;
&lt;span style=&quot;color: #b58900&quot;&gt;Time&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;at&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;1617443220&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt;     &lt;span style=&quot;color: #657b83&quot;&gt;# same as above but using timestamp&lt;/span&gt;
&lt;span style=&quot;color: #b58900&quot;&gt;Time&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;now&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;monday?&lt;/span&gt;        &lt;span style=&quot;color: #657b83&quot;&gt;# indicates if date is monday&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;A few more examples:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #859900&quot;&gt;123&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;digits&lt;/span&gt;                  &lt;span style=&quot;color: #657b83&quot;&gt;# produces [3, 2, 1]&lt;/span&gt;
&lt;span style=&quot;color: #859900&quot;&gt;&quot;Test&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;chars&lt;/span&gt;                &lt;span style=&quot;color: #657b83&quot;&gt;# produces [&quot;T&quot;, &quot;e&quot;, &quot;s&quot;, &quot;t&quot;]&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;].&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;combination&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt;    &lt;span style=&quot;color: #657b83&quot;&gt;# need combinations of array elements?&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;].&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;permutation&lt;/span&gt;       &lt;span style=&quot;color: #657b83&quot;&gt;# or maybe permutations?&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;nil&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #6c71c4&quot;&gt;nil&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;].&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;compact&lt;/span&gt; &lt;span style=&quot;color: #657b83&quot;&gt;# returns new array without nil values&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;[[&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;],&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;]].&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;flatten&lt;/span&gt;    &lt;span style=&quot;color: #657b83&quot;&gt;# produces [1, 2, 3, 4]&lt;/span&gt;
&lt;span style=&quot;color: #93a1a1&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;].&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;rotate&lt;/span&gt;            &lt;span style=&quot;color: #657b83&quot;&gt;# produces [2, 3, 1]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Super handy and readable! Especially compared to e.g. the standard JavaScript library which is very poor.&lt;/p&gt;

&lt;p&gt;I really encourage you to review the documentation because Ruby has a lot more interesting features.&lt;/p&gt;

&lt;h2 id=&quot;deeply-ingrained-testing-culture&quot;&gt;Deeply ingrained testing culture&lt;/h2&gt;

&lt;p&gt;Should I write tests or not? This is obvious to Ruby programmers. They just write tests. It’s part of their culture. I am writing about it because it is not so obvious in other technologies.&lt;/p&gt;

&lt;p&gt;Have you ever worked on any legacy projects without a single unit test? I used to and it was a traumatic experience. Ruby developers starting to work with legacy code can expect their code was somehow tested. It is better to have slow or low quality tests than none.&lt;/p&gt;

&lt;h2 id=&quot;ive-seen-it-somewhere-before&quot;&gt;I’ve seen it somewhere before…&lt;/h2&gt;

&lt;p&gt;As I said before, I am a full time .NET developer. I am really accustomed to C# and its features such as Linq.&lt;/p&gt;

&lt;p&gt;I love the way I can chain Linq methods. And guess what… Ruby has very similar feature! Take a look at this two code snippets (first is C#, second is Ruby):&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #6c71c4&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #cb4b16&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;[]&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;&quot;Tom&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;&quot;Jerry&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;&quot;Spike&quot;&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Where&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;x&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;x&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Contains&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;&apos;e&apos;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;))&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Select&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;x&lt;/span&gt; &lt;span style=&quot;color: #93a1a1&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;x&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Length&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;Sum&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #859900&quot;&gt;&quot;Tom&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;&quot;Jerry&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;&quot;Spike&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;]&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;filter&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;x&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;|&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;x&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;include?&lt;/span&gt; &lt;span style=&quot;color: #859900&quot;&gt;&quot;e&quot;&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;x&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;|&lt;/span&gt; &lt;span style=&quot;color: #586e75&quot;&gt;x&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color: #93a1a1&quot;&gt;}&lt;/span&gt;
    &lt;span style=&quot;color: #93a1a1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #586e75&quot;&gt;sum&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;At first glance, you can see that both pieces of code do exactly the same thing. For me both method chains are clearly traceable, readable and very elegant.&lt;/p&gt;

&lt;h2 id=&quot;remote-work&quot;&gt;Remote work&lt;/h2&gt;

&lt;p&gt;Finally, remote work is very popular in the Ruby world. Most of the Ruby programmers worked this way before it became so popular in the pandemic era. For me personally, remote work is the best way to work. This is a huge time saver.&lt;/p&gt;

&lt;h2 id=&quot;final-thoughts&quot;&gt;Final thoughts&lt;/h2&gt;

&lt;p&gt;I have to admit, Ruby programming is very enjoyable. It definitely deserves to dive deeper into its features.
It’s hard for me to find something that I don’t like.&lt;/p&gt;

&lt;p&gt;I think the next step is to look at the Ruby on Rails framework. I’ve heard a lot of good feedback about it. Especially about how efficient and productive it is to create an application using it.&lt;/p&gt;

&lt;p&gt;If you have any interesting thoughts on this topic, let me know!&lt;/p&gt;</content><author><name>Mikołaj Kamiński</name><email>your-email@domain.com</email></author><category term="thoughts" /><category term="ruby" /><summary type="html">I am a full time .NET developer, but I have been interested in Ruby for some time. Not very professional, but I liked this technology very much. I would like to share why I think so.</summary></entry></feed>