<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Stuart Lang</title>
    <description>The latest articles on DEV Community by Stuart Lang (@stuartblang).</description>
    <link>https://dev.to/stuartblang</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F143970%2F58e227f5-8099-4c40-9baf-6f37ecf5e96b.jpg</url>
      <title>DEV Community: Stuart Lang</title>
      <link>https://dev.to/stuartblang</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/stuartblang"/>
    <language>en</language>
    <item>
      <title>Xamarin Forms Accessible Headings</title>
      <dc:creator>Stuart Lang</dc:creator>
      <pubDate>Mon, 02 Sep 2019 18:34:00 +0000</pubDate>
      <link>https://dev.to/stuartblang/xamarin-forms-accessible-headings-2192</link>
      <guid>https://dev.to/stuartblang/xamarin-forms-accessible-headings-2192</guid>
      <description>&lt;p&gt;If you are developing a mobile app, it's worth enabling VoiceOver on iOS and considering the usability from the perspective of people who rely on these tools to access your app.&lt;/p&gt;

&lt;p&gt;Out of the box, Xamarin Forms comes with some nice accessibility features that can control the VoiceOver experience, in particular &lt;a href="https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/accessibility/automation-properties"&gt;Automation Properties&lt;/a&gt; allow you to annotate your XAML elements with metadata such as what text to read out when selected by VoiceOver.&lt;/p&gt;

&lt;p&gt;In this post I won't be focusing on these features, but instead, looking at &lt;em&gt;Headings&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Headings
&lt;/h3&gt;

&lt;p&gt;Consider the following screen:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wHamBRwg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://stu.dev/content/images/2019/08/image-5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wHamBRwg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://stu.dev/content/images/2019/08/image-5.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Visually, these headers convey the structure of the screen to the user. However, now let's try to navigate the page using solely VoiceOver. In this animation as we swipe left/right, the previous/next element is selected and its description is read aloud.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ny0-2p3O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://stu.dev/content/images/2019/09/before.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ny0-2p3O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://stu.dev/content/images/2019/09/before.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While all the content can be accessed, the headings just fade into the regular content if VoiceOver is your only UI.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--x91U9XW2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://stu.dev/content/images/2019/08/image-9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--x91U9XW2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://stu.dev/content/images/2019/08/image-9.png" alt=""&gt;&lt;/a&gt;Rotor control&lt;/p&gt;

&lt;p&gt;Let's try using the Rotor navigation control to select &lt;code&gt;Headings&lt;/code&gt; (with a two-finger twist gesture). Now we can navigate the screen by jumping through the headers with a swipe up/down gesture, however at the moment VoiceOver just says: "No Headings Found", which isn't very helpful.&lt;/p&gt;

&lt;p&gt;On iOS, elements can be given a &lt;code&gt;header&lt;/code&gt; &lt;a href="https://developer.apple.com/documentation/uikit/accessibility/uiaccessibility/accessibility_traits"&gt;accessibility trait&lt;/a&gt;. Using this, VoiceOver considers these elements as headings, and the swipe up/down gesture will now work and jump the selection to the next/previous heading.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jHFXOKfw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://stu.dev/content/images/2019/09/after.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jHFXOKfw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://stu.dev/content/images/2019/09/after.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This now functions much better as we can quick-jump between headings and still navigate to the items around them. Now let's build it.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do we do it?
&lt;/h3&gt;

&lt;p&gt;It turns out we don't need much code to make this happen. We'll create an attached property that will automatically add an effect to the element it's added to.&lt;/p&gt;

&lt;p&gt;We first need to define our attached property, and create the effect which will be implemented only for iOS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Linq&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Xamarin.Forms&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;XamAppWithHeaders&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Accessibility&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Flags&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;AccessibilityTrait&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Header&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;BindableProperty&lt;/span&gt; &lt;span class="n"&gt;AccessibilityTraitsProperty&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
            &lt;span class="n"&gt;BindableProperty&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateAttached&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"AccessibilityTraits"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AccessibilityTrait&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Accessibility&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;AccessibilityTrait&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;propertyChanged&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;OnAccessibilityTraitsChanged&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;AccessibilityTrait&lt;/span&gt; &lt;span class="nf"&gt;GetAccessibilityTraits&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BindableObject&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AccessibilityTrait&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AccessibilityTraitsProperty&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;SetAccessibilityTraits&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BindableObject&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AccessibilityTrait&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AccessibilityTraitsProperty&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;OnAccessibilityTraitsChanged&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BindableObject&lt;/span&gt; &lt;span class="n"&gt;bindable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;oldValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;newValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!(&lt;/span&gt;&lt;span class="n"&gt;bindable&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;View&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;newTraits&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AccessibilityTrait&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;newValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;hasTraits&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;newTraits&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;AccessibilityTrait&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;None&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hasTraits&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Effects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OfType&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AccessibilityTraitEffect&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;().&lt;/span&gt;&lt;span class="nf"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Effects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;AccessibilityTraitEffect&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;accessibilityTrait&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Effects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OfType&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AccessibilityTraitEffect&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;().&lt;/span&gt;&lt;span class="nf"&gt;FirstOrDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;accessibilityTrait&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Effects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;accessibilityTrait&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AccessibilityTraitEffect&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;RoutingEffect&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;AccessibilityTraitEffect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"XamAppWithHeaders.AccessibilityTraitEffect"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Be sure to change &lt;code&gt;XamAppWithHeaders&lt;/code&gt; in the &lt;code&gt;RoutingEffect&lt;/code&gt; base call to match your own namespace.&lt;/p&gt;

&lt;p&gt;Now in our iOS project we will implement the effect and actually set the accessibility trait:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;UIKit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Xamarin.Forms&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Xamarin.Forms.Platform.iOS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;static&lt;/span&gt; &lt;span class="n"&gt;XamAppWithHeaders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Accessibility&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;assembly&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;ResolutionGroupName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"XamAppWithHeaders"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;assembly&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;ExportEffect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;XamAppWithHeaders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iOS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AccessibilityTraitEffect&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;"AccessibilityTraitEffect"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;

&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;XamAppWithHeaders.iOS&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AccessibilityTraitEffect&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;PlatformEffect&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;OnAttached&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;AddAccessibilityTraits&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;OnDetached&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;OnElementPropertyChanged&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ComponentModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PropertyChangedEventArgs&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PropertyName&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;AccessibilityTraitsProperty&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PropertyName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nf"&gt;AddAccessibilityTraits&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;OnElementPropertyChanged&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;AddAccessibilityTraits&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;traits&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Control&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AccessibilityTraits&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;newTraits&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;GetAccessibilityTraits&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Element&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;newTraits&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;AccessibilityTrait&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;traits&lt;/span&gt; &lt;span class="p"&gt;|=&lt;/span&gt; &lt;span class="n"&gt;UIAccessibilityTrait&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="n"&gt;Control&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AccessibilityTraits&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;traits&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;... and that's it, we can now bring the namespace into our xaml view and add it to any elements that we want to indicate as a heading.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;Label&lt;/span&gt; &lt;span class="na"&gt;local:Accessibility.AccessibilityTraits=&lt;/span&gt;&lt;span class="s"&gt;"Header"&lt;/span&gt; &lt;span class="na"&gt;Text=&lt;/span&gt;&lt;span class="s"&gt;"First Header"&lt;/span&gt; &lt;span class="na"&gt;Style=&lt;/span&gt;&lt;span class="s"&gt;"{StaticResource headerStyle}"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;However, you can see that we already have a shared style for heading as is often the case with a real world app, in this case &lt;code&gt;headerStyle&lt;/code&gt;. It turns out that you can add attached properties via a shared style, which looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;Style&lt;/span&gt; &lt;span class="na"&gt;x:Key=&lt;/span&gt;&lt;span class="s"&gt;"headerStyle"&lt;/span&gt; &lt;span class="na"&gt;TargetType=&lt;/span&gt;&lt;span class="s"&gt;"Label"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Setter&lt;/span&gt; &lt;span class="na"&gt;Property=&lt;/span&gt;&lt;span class="s"&gt;"FontAttributes"&lt;/span&gt; &lt;span class="na"&gt;Value=&lt;/span&gt;&lt;span class="s"&gt;"Bold"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Setter&lt;/span&gt; &lt;span class="na"&gt;Property=&lt;/span&gt;&lt;span class="s"&gt;"FontSize"&lt;/span&gt; &lt;span class="na"&gt;Value=&lt;/span&gt;&lt;span class="s"&gt;"22"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Setter&lt;/span&gt; &lt;span class="na"&gt;Property=&lt;/span&gt;&lt;span class="s"&gt;"local:Accessibility.AccessibilityTraits"&lt;/span&gt; &lt;span class="na"&gt;Value=&lt;/span&gt;&lt;span class="s"&gt;"Header"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/Style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Closing Thoughts
&lt;/h3&gt;

&lt;p&gt;With just 2 code files and 1 line added to your heading styles, it couldn't be much simpler to make your app more accessible for people who rely on VoiceOver. Give it a try 😀&lt;/p&gt;

&lt;p&gt;A working sample can be found &lt;a href="https://github.com/slang25/xamarin-forms-accessiblity-traits-demo"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>xamarin</category>
      <category>xamarinforms</category>
      <category>a11y</category>
    </item>
    <item>
      <title>Testing with HttpClient Interception</title>
      <dc:creator>Stuart Lang</dc:creator>
      <pubDate>Sun, 24 Mar 2019 20:45:24 +0000</pubDate>
      <link>https://dev.to/stuartblang/testing-with-httpclient-interception-304f</link>
      <guid>https://dev.to/stuartblang/testing-with-httpclient-interception-304f</guid>
      <description>&lt;p&gt;&lt;a href="https://dev.to/stuartblang/generating-a-typed-client-for-use-with-httpclientfactory-using-nswag-3e86"&gt;In my last post&lt;/a&gt; I showed how to automatically generate a typed client for use with &lt;code&gt;HttpClientFactory&lt;/code&gt; from a swagger file. Now I want to make changes to the client's behaviour and need unit tests, in this post I will look at the &lt;a href="https://github.com/justeat/httpclient-interception/" rel="noopener noreferrer"&gt;HttpClient Interception&lt;/a&gt; library and how we can effectively use it in our tests.&lt;/p&gt;

&lt;p&gt;Take a look at the following code that makes use of our previously generated client.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pet&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;petStoreClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetPetByIdAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ct&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;firstTag&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FirstOrDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This looks fine, right? But what happens if &lt;code&gt;Tags&lt;/code&gt; is &lt;code&gt;null&lt;/code&gt;? Can that event happen?&lt;/p&gt;

&lt;p&gt;The quick fix would be to use &lt;code&gt;?.&lt;/code&gt; to propagate null safety, but maybe we want our deserialization to never allow collections to be null, but to instead default it to an empty collection.&lt;/p&gt;

&lt;p&gt;To figure out the current behaviour and to document how we'd like it to work, we should write tests.&lt;/p&gt;

&lt;p&gt;I will be writing these tests in F#, 'cos it rocks! Not only is it a really nice language, I want to use string literals containing JSON in my tests, and this is painful in C#.&lt;/p&gt;

&lt;h2&gt;
  
  
  HttpClient Interception
&lt;/h2&gt;

&lt;p&gt;This library is really slick, it has a fluent API that can produce an &lt;code&gt;HttpClient&lt;/code&gt; loaded with an &lt;code&gt;HttpClientHandler&lt;/code&gt; that will intercept requests and return configured responses, so it's great for unit testing.&lt;/p&gt;

&lt;p&gt;The fluent API is really intuitive, you can see some great examples on the &lt;a href="https://github.com/justeat/httpclient-interception/" rel="noopener noreferrer"&gt;README&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight fsharp"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;NSwag&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;PetStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;Tests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Tests&lt;/span&gt;

&lt;span class="k"&gt;open&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;
&lt;span class="k"&gt;open&lt;/span&gt; &lt;span class="nc"&gt;Xunit&lt;/span&gt;
&lt;span class="k"&gt;open&lt;/span&gt; &lt;span class="nn"&gt;NSwag&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;PetStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Client&lt;/span&gt;
&lt;span class="k"&gt;open&lt;/span&gt; &lt;span class="nn"&gt;JustEat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;HttpClientInterception&lt;/span&gt;

&lt;span class="p"&gt;[&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;]&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;``Given missing collection property, we deserialize to an empty collection. 🚀``&lt;/span&gt; &lt;span class="bp"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
        &lt;span class="nc"&gt;HttpRequestInterceptionBuilder&lt;/span&gt;&lt;span class="bp"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Requests&lt;/span&gt;&lt;span class="bp"&gt;()&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ForAnyHost&lt;/span&gt;&lt;span class="bp"&gt;()&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ForPath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"/pet/1234"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Responds&lt;/span&gt;&lt;span class="bp"&gt;()&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;WithContent&lt;/span&gt; &lt;span class="s2"&gt;"""{
  "&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="s2"&gt;": 0,
  "&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="s2"&gt;": "&lt;/span&gt;&lt;span class="n"&gt;doggie&lt;/span&gt;&lt;span class="s2"&gt;",
  "&lt;/span&gt;&lt;span class="n"&gt;photoUrls&lt;/span&gt;&lt;span class="s2"&gt;": [
    "&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="s2"&gt;"
  ],
  "&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="s2"&gt;": "&lt;/span&gt;&lt;span class="n"&gt;available&lt;/span&gt;&lt;span class="s2"&gt;"
}"""&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;  &lt;span class="nc"&gt;HttpClientInterceptorOptions&lt;/span&gt;&lt;span class="bp"&gt;()&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ThrowsOnMissingRegistration&lt;/span&gt;&lt;span class="bp"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;RegisterWith&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ignore&lt;/span&gt;
    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="n"&gt;innerClient&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CreateHttpClient&lt;/span&gt;&lt;span class="bp"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;innerClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;BaseAddress&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="s2"&gt;"http://test-host"&lt;/span&gt; &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Uri&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;PetStoreClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;innerClient&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;pet&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;GetPetByIdAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1234&lt;/span&gt;&lt;span class="nc"&gt;L&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;Async&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;AwaitTask&lt;/span&gt; &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;Async&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;RunSynchronously&lt;/span&gt;

    &lt;span class="nn"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;NotNull&lt;/span&gt; &lt;span class="n"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Tags&lt;/span&gt;
    &lt;span class="nn"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Empty&lt;/span&gt; &lt;span class="n"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Tags&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some things to call out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We're using &lt;code&gt;xUnit&lt;/code&gt;, another great choice would be &lt;a href="https://github.com/haf/expecto" rel="noopener noreferrer"&gt;Expecto&lt;/a&gt;, however there's no test runner yet for Rider, and xUnit will work just fine here. xUnit works pretty well with F#, we don't have to have class definitions, notice how we have a module here, but as soon as we want to use &lt;code&gt;ITestOutputHelper&lt;/code&gt; we have to switch to using classes.&lt;/li&gt;
&lt;li&gt;Function names in F# can contain pretty much anything by escaping with double-ticks: spaces, punctuation, even emojis (which means you have to use them, surely!).&lt;/li&gt;
&lt;li&gt;String literals can contain &lt;code&gt;"&lt;/code&gt; when we use triple-quoted strings - this is great for JSON and XML snippets.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In terms of what we are doing with HttpClient Interceptor, it almost needs no explanation as it's completely declarative, the only comment I'd add is that you'll probably want the &lt;code&gt;ThrowsOnMissingRegistration&lt;/code&gt; during tests, as this ensures everything is completely in-memory, and nothing passes through and materialises to an actual HTTP request .&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstu.dev%2Fcontent%2Fimages%2F2019%2F03%2Fimage.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstu.dev%2Fcontent%2Fimages%2F2019%2F03%2Fimage.png"&gt;&lt;/a&gt;As we suspected!&lt;/p&gt;

&lt;p&gt;Right, so if the &lt;code&gt;Tag&lt;/code&gt; part of the JSON is omitted then we end up with a null collection, which is not what we want, so let's change it.&lt;/p&gt;

&lt;p&gt;NSwag lets us control the serialization settings in a few ways, one way is via the &lt;code&gt;jsonSerializerSettingsTransformationMethod&lt;/code&gt; setting, it lets us point to a static method to configure the &lt;code&gt;JsonSerializerSettings&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;After lots of investigation, I found that this was the simplest way to achieve the deserialization that I wanted:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Collections.Generic&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Reflection&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Newtonsoft.Json&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Newtonsoft.Json.Serialization&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;NSwag.PetStore.Client&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PetStoreSerializerSettings&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;JsonSerializerSettings&lt;/span&gt; &lt;span class="nf"&gt;TransformSettings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;JsonSerializerSettings&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DefaultValueHandling&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DefaultValueHandling&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Populate&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ContractResolver&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;NullToEmptyListResolver&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;sealed&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NullToEmptyListResolver&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;DefaultContractResolver&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="n"&gt;JsonProperty&lt;/span&gt; &lt;span class="nf"&gt;CreateProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MemberInfo&lt;/span&gt; &lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MemberSerialization&lt;/span&gt; &lt;span class="n"&gt;memberSerialization&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;property&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;memberSerialization&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;propType&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;property&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PropertyType&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;propType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsGenericType&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; 
                &lt;span class="n"&gt;propType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetGenericTypeDefinition&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ICollection&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&amp;gt;))&lt;/span&gt;
                &lt;span class="n"&gt;property&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NullValueHandling&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;NullValueHandling&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Include&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;property&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="n"&gt;IValueProvider&lt;/span&gt; &lt;span class="nf"&gt;CreateMemberValueProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MemberInfo&lt;/span&gt; &lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;provider&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateMemberValueProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MemberType&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;MemberTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Property&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;propType&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;PropertyInfo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;PropertyType&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;propType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsGenericType&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; 
                    &lt;span class="n"&gt;propType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetGenericTypeDefinition&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ICollection&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&amp;gt;))&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;EmptyListValueProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;propType&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EmptyListValueProvider&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IValueProvider&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IValueProvider&lt;/span&gt; &lt;span class="n"&gt;innerProvider&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;defaultValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;EmptyListValueProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IValueProvider&lt;/span&gt; &lt;span class="n"&gt;innerProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;listType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;innerProvider&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;innerProvider&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="n"&gt;defaultValue&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateInstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;listType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetGenericArguments&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;SetValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;innerProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt; &lt;span class="p"&gt;??&lt;/span&gt; &lt;span class="n"&gt;defaultValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="nf"&gt;GetValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;innerProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;??&lt;/span&gt; &lt;span class="n"&gt;defaultValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If there is a simpler way (and I suspect there must be!) do let me know in the comments.&lt;/p&gt;

&lt;p&gt;Now when we run the tests again...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstu.dev%2Fcontent%2Fimages%2F2019%2F03%2Fimage-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstu.dev%2Fcontent%2Fimages%2F2019%2F03%2Fimage-1.png"&gt;&lt;/a&gt;That's better 🙂&lt;/p&gt;

&lt;h2&gt;
  
  
  Other Options with HttpClient Interception
&lt;/h2&gt;

&lt;p&gt;In this case I wanted my test to contain a JSON string literal, but in most cases we could instead use the &lt;code&gt;WithJsonContent&lt;/code&gt; method, which takes an object and serializes it for us (optionally with serialization settings). Ironically it would have been easier in C# if I wanted to do this, as anonymous objects hasn't yet landed in F# (but it's sooo close!).&lt;/p&gt;

&lt;p&gt;A compelling alternative would have been to use an &lt;a href="https://github.com/justeat/httpclient-interception#http-bundle-files" rel="noopener noreferrer"&gt;HTTP bundle&lt;/a&gt; file, which to quote the docs, “can be used to store the HTTP requests to intercept and [store] their corresponding responses as JSON”.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;HttpClient Interception is the &lt;a href="https://github.com/justeat/httpclient-interception/graphs/contributors" rel="noopener noreferrer"&gt;brainchild&lt;/a&gt; of &lt;a href="https://twitter.com/martin_costello" rel="noopener noreferrer"&gt;Martin Costello&lt;/a&gt;, who's always doing amazing things in the .NET Core community.&lt;/p&gt;

&lt;p&gt;You can find all of the &lt;a href="https://github.com/slang25/nswag-petstore-client/tree/httpclient-interception" rel="noopener noreferrer"&gt;code in this post here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>fsharp</category>
      <category>csharp</category>
      <category>dotnetcore</category>
    </item>
    <item>
      <title>Generating a Typed Client for use with HttpClientFactory using NSwag</title>
      <dc:creator>Stuart Lang</dc:creator>
      <pubDate>Mon, 18 Mar 2019 09:29:42 +0000</pubDate>
      <link>https://dev.to/stuartblang/generating-a-typed-client-for-use-with-httpclientfactory-using-nswag-3e86</link>
      <guid>https://dev.to/stuartblang/generating-a-typed-client-for-use-with-httpclientfactory-using-nswag-3e86</guid>
      <description>&lt;p&gt;If you're a .NET developer building web apps or microservices, odds are at some point you're going to want to call an HTTP API from an ASP.NET Core app. This post covers how to create a client using NSwag, with the appropriate settings for using it with &lt;code&gt;HttpClientFactory&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Typed Clients and &lt;code&gt;HttpClientFactory&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;For a proper introduction to these concepts I encourage you to read &lt;a href="https://twitter.com/stevejgordon"&gt;Steve Gordon&lt;/a&gt;'s HttpClientFactory in ASP.NET Core 2.1 series, &lt;a href="https://www.stevejgordon.co.uk/introduction-to-httpclientfactory-aspnetcore"&gt;An Introduction to HttpClientFactory&lt;/a&gt; and &lt;a href="https://www.stevejgordon.co.uk/httpclientfactory-named-typed-clients-aspnetcore"&gt;Defining Named and Typed Clients&lt;/a&gt;, but the really short version is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;HttpClientFactory&lt;/code&gt; - This was introduced to solve the problems around managing the lifetime of &lt;code&gt;HttpClient&lt;/code&gt;s and their handlers, which historically has been problematic.&lt;/li&gt;
&lt;li&gt;Typed Clients - This is a feature of &lt;code&gt;HttpClientFactory&lt;/code&gt; which lets you register a class which simply wraps &lt;code&gt;HttpClient&lt;/code&gt; (i.e. takes one in its constructor), thus giving you a typed client to your API, while not owning the lifetime of any &lt;code&gt;HttpClient&lt;/code&gt;s, letting &lt;code&gt;HttpClientFactory&lt;/code&gt; do its thing.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  NSwag
&lt;/h2&gt;

&lt;p&gt;Where does &lt;a href="http://nswag.org"&gt;NSwag&lt;/a&gt; fit into this?&lt;/p&gt;

&lt;p&gt;NSwag is, on one hand, like &lt;a href="https://github.com/domaindrivendev/Swashbuckle.AspNetCore"&gt;Swashbuckle&lt;/a&gt;, in that with a couple of lines of code you can have your ASP.NET Core application serving up a swagger doc and swagger ui within your app at runtime. Then it also has the functionality of &lt;a href="https://github.com/Azure/autorest"&gt;AutoRest&lt;/a&gt;, where it can take a swagger file and generate a C# typed client for you (and other languages such as TypeScript).&lt;/p&gt;

&lt;p&gt;There are a couple of things that impress me about NSwag:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The number of integrations - it's a swiss army knife! Just take a minute to read the &lt;a href="https://github.com/RSuter/NSwag/blob/master/README.md"&gt;README&lt;/a&gt;, you quickly get the idea, it can generate swagger or OpenAPI file not just at runtime, but at build time from your web api assembly. Then you can generate clients in various languages with lots of settings to play around with.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://twitter.com/RicoSuter"&gt;Rico Suter&lt;/a&gt;, who is the primary maintainer, is continuously contributing to it and is so responsive to issues, and checking in fixes and features. It's like he has a team running his GitHub account!&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Starting with swagger.json
&lt;/h2&gt;

&lt;p&gt;We are going to be generating a client from &lt;code&gt;swagger.json&lt;/code&gt;, if you need to produce this from your own ASP.NET Core application then you can generate a &lt;code&gt;swagger.json&lt;/code&gt; using the NSwag CLI, &lt;a href="https://github.com/RSuter/NSwag/wiki/AspNetCoreToSwaggerCommand"&gt;see here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generating the Client in Build
&lt;/h2&gt;

&lt;p&gt;For this, we will use the &lt;code&gt;NSwag.ConsoleCore&lt;/code&gt; CLI tool package (we could also use the &lt;a href="https://www.nuget.org/packages/NSwag.MSBuild/"&gt;NSwag.MSBuild&lt;/a&gt; package, the process is largely the same). I'm using the &lt;a href="https://petstore.swagger.io/#/"&gt;Pet Store swagger&lt;/a&gt;, and start by dropping the &lt;code&gt;swagger.json&lt;/code&gt; into my project folder.&lt;/p&gt;

&lt;p&gt;There are 2 ways to pass config into the NSwag commands, one is via command line args, the other is via a JSON config file which is what I'll be using here.&lt;/p&gt;

&lt;p&gt;Firs create an empty library (here we will target &lt;code&gt;netstandard2.0&lt;/code&gt;) and add the following snippet to an &lt;code&gt;ItemGroup&lt;/code&gt; in your &lt;code&gt;.csproj&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;DotNetCliToolReference&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"NSwag.ConsoleCore"&lt;/span&gt; &lt;span class="na"&gt;Version=&lt;/span&gt;&lt;span class="s"&gt;"12.0.15"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;After a &lt;code&gt;dotnet restore&lt;/code&gt; we can now run in the project folder &lt;code&gt;dotnet nswag new&lt;/code&gt;, this will create us a default config file, we can strip it down so it &lt;a href="https://github.com/slang25/nswag-petstore-client/blob/master/NSwag.PetStore.Client/nswag.json"&gt;looks like this&lt;/a&gt;. Here's a trimmed down version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"runtime"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"NetCore22"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"defaultVariables"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"swaggerGenerator"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"fromSwagger"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"json"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"$(InputSwagger)"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"codeGenerators"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"swaggerToCSharpClient"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;OMITTING&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;LOTS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;OF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;DEFAULT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;CONFIG&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"generateClientInterfaces"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"injectHttpClient"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"disposeHttpClient"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"generateExceptionClasses"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exceptionClass"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"$(ClientName)Exception"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"useBaseUrl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"className"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"$(ClientName)Client"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"generateOptionalParameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"generateJsonMethods"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"namespace"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"$(ClientNamespace)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"classStyle"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Poco"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"output"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"$(GeneratedSwaggerClientFile)"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here are settings that I changed from their defaults:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;generateClientInterfaces&lt;/code&gt; - This gives us an interface for our typed client, abstracting the implementation away. This may seem like something you wouldn't think of doing without, but there is merit in using the implementation of the typed client under test and mocking at the &lt;code&gt;HttpClient&lt;/code&gt; level (shout out to &lt;a href="https://github.com/justeat/httpclient-interception"&gt;httpclient-interception&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;InjectHttpClient&lt;/code&gt; - This creates a constructor to the client that takes in a &lt;code&gt;HttpClient&lt;/code&gt;, which is what we need to use it as a typed client with &lt;code&gt;HttpClientFactory&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;disposeHttpClient&lt;/code&gt; - It mostly doesn't matter if you call &lt;code&gt;Dispose&lt;/code&gt; on &lt;code&gt;HttpClient&lt;/code&gt; when used with &lt;code&gt;HttpClientFactory&lt;/code&gt;, it's mostly a no-op. However, for correctness sake, it would be weird for the typed client to dispose of something it doesn't own.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;generateOptionalParameters&lt;/code&gt; - By default NSwag will create 2 methods per operation, one with and one without a &lt;code&gt;CancellationToken&lt;/code&gt;, enabling this will combine them.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;generateJsonMethods&lt;/code&gt; - By default NSwag will add instance methods that serialize and deserialize types, they just delegate to one-liner static methods from Json.NET. I like my POCOs nice and plain, so I disable this.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;useBaseUrl&lt;/code&gt; - This is an important one, we want to use the &lt;code&gt;BaseAddress&lt;/code&gt; of &lt;code&gt;HttpClient&lt;/code&gt; only, we don't want to override that with a property on the typed client (which is what will happen by default), so we set this to &lt;code&gt;false&lt;/code&gt;. We can configure the &lt;code&gt;BaseAddress&lt;/code&gt; at the time we register the typed client.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;exceptionClass&lt;/code&gt; - The type of exception that is thrown on error, by default it would be &lt;code&gt;SwaggerException&lt;/code&gt;, which feels like an implementation leak.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;classStyle&lt;/code&gt; - By default NSwag uses the style &lt;code&gt;Inpc&lt;/code&gt; which is short for &lt;code&gt;INotifyPropertyChange&lt;/code&gt;, which is a strange default, I can only think it would be useful if you were building an MVVM client app and wanted to reuse the classes to bind to directly (still feels wrong to me). By selecting &lt;code&gt;Poco&lt;/code&gt;, we end up with just a typical class with getter and setter properties.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can see I use variables in this file, such as &lt;code&gt;"$(InputSwagger)"&lt;/code&gt;, we can pass these in via the &lt;code&gt;nswag&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;What we want to do is to just do a &lt;code&gt;dotnet build&lt;/code&gt; and to have the project automatically create the generated &lt;code&gt;.cs&lt;/code&gt; file, and include it in the files to build. So here's the &lt;code&gt;.csproj&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;Project&lt;/span&gt; &lt;span class="na"&gt;Sdk=&lt;/span&gt;&lt;span class="s"&gt;"Microsoft.NET.Sdk"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;PropertyGroup&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;TargetFramework&amp;gt;&lt;/span&gt;netstandard2.0&lt;span class="nt"&gt;&amp;lt;/TargetFramework&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;DebugType&amp;gt;&lt;/span&gt;embedded&lt;span class="nt"&gt;&amp;lt;/DebugType&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;EmbedAllSources&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/EmbedAllSources&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/PropertyGroup&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ItemGroup&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;PackageReference&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"Newtonsoft.Json"&lt;/span&gt; &lt;span class="na"&gt;Version=&lt;/span&gt;&lt;span class="s"&gt;"12.0.1"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;PackageReference&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"System.ComponentModel.Annotations"&lt;/span&gt; &lt;span class="na"&gt;Version=&lt;/span&gt;&lt;span class="s"&gt;"4.5.0"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;DotNetCliToolReference&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"NSwag.ConsoleCore"&lt;/span&gt; &lt;span class="na"&gt;Version=&lt;/span&gt;&lt;span class="s"&gt;"12.0.15"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/ItemGroup&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;Target&lt;/span&gt; &lt;span class="na"&gt;Name=&lt;/span&gt;&lt;span class="s"&gt;"GenerateNSwagClient"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;PropertyGroup&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;InputSwagger&amp;gt;&lt;/span&gt;swagger.json&lt;span class="nt"&gt;&amp;lt;/InputSwagger&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;ClientName&amp;gt;&lt;/span&gt;PetStore&lt;span class="nt"&gt;&amp;lt;/ClientName&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;GeneratedSwaggerClientFile&lt;/span&gt; &lt;span class="na"&gt;Condition=&lt;/span&gt;&lt;span class="s"&gt;"'$(GeneratedSwaggerClientFile)' ==''"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;$(IntermediateOutputPath)$(MSBuildProjectName).$(ClientName)Client.cs&lt;span class="nt"&gt;&amp;lt;/GeneratedSwaggerClientFile&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/PropertyGroup&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;Exec&lt;/span&gt; &lt;span class="na"&gt;Command=&lt;/span&gt;&lt;span class="s"&gt;"dotnet nswag run nswag.json /variables:InputSwagger=$(InputSwagger),ClientName=$(ClientName),ClientNamespace=$(RootNamespace),GeneratedSwaggerClientFile=$(GeneratedSwaggerClientFile)"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/Target&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;Target&lt;/span&gt; &lt;span class="na"&gt;Name=&lt;/span&gt;&lt;span class="s"&gt;"IncludeNSwagClient"&lt;/span&gt; &lt;span class="na"&gt;BeforeTargets=&lt;/span&gt;&lt;span class="s"&gt;"CoreCompile"&lt;/span&gt; &lt;span class="na"&gt;DependsOnTargets=&lt;/span&gt;&lt;span class="s"&gt;"GenerateNSwagClient"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;ItemGroup&lt;/span&gt; &lt;span class="na"&gt;Condition=&lt;/span&gt;&lt;span class="s"&gt;"Exists('$(GeneratedSwaggerClientFile)')"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;Compile&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"$(GeneratedSwaggerClientFile)"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;FileWrites&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"$(GeneratedSwaggerClientFile)"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/ItemGroup&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/Target&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/Project&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Things to note:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The only thing in this file that is specific to the Pet Store swagger, is the &lt;code&gt;&amp;lt;ClientName&amp;gt;PetStore&amp;lt;/ClientName&amp;gt;&lt;/code&gt;, feel free to use this as a recipe for your own clients.&lt;/li&gt;
&lt;li&gt;We hook our targets before &lt;code&gt;CoreCompile&lt;/code&gt;, giving us the opportunity to add files to compile.&lt;/li&gt;
&lt;li&gt;The generated file goes into the &lt;code&gt;IntermediateOutputPath&lt;/code&gt;, this is the configuration-specific folder inside of &lt;code&gt;obj&lt;/code&gt;, this is exactly how &lt;code&gt;AssemblyInfo.cs&lt;/code&gt; is generated, and is likely already part of your &lt;code&gt;.gitignore&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;We have included the required &lt;code&gt;Newtonsoft.Json&lt;/code&gt; and &lt;code&gt;System.ComponentModel.Annotations&lt;/code&gt; packages.&lt;/li&gt;
&lt;li&gt;Variables are passed into the &lt;code&gt;nswag.json&lt;/code&gt; using the &lt;code&gt;variables&lt;/code&gt; argument.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;DebugType&amp;gt;embedded&amp;lt;/DebugType&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;EmbedAllSources&amp;gt;true&amp;lt;/EmbedAllSources&amp;gt;&lt;/code&gt; gives us one &lt;code&gt;.dll&lt;/code&gt; which contains an embedded PDB file, which contains all of the source within it for debugging purposes. You could also use &lt;a href="https://docs.microsoft.com/en-us/nuget/create-packages/symbol-packages-snupkg"&gt;symbol packages&lt;/a&gt;, which in my option is a step backwards from this solution.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Using the Client with &lt;code&gt;HttpClientFactory&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Right, we have our package/project, let's use it!&lt;/p&gt;

&lt;p&gt;Let's create a new ASP.NET Core Web API using the template, and add a reference to our client project and add the &lt;code&gt;Microsoft.Extensions.Http&lt;/code&gt; package. &lt;a href="https://github.com/slang25/nswag-petstore-client/blob/master/SampleApp/SampleApp.csproj"&gt;See here&lt;/a&gt; for an example.&lt;/p&gt;

&lt;p&gt;Now we can register our client in the &lt;code&gt;ConfigureServices&lt;/code&gt; method, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddHttpClient&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IPetStoreClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PetStoreClient&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BaseAddress&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://petstore.swagger.io/v2/"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And that's it! Now we can start using our client, here's an example from our controller:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"api/[controller]"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ApiController&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ValuesController&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ControllerBase&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IPetStoreClient&lt;/span&gt; &lt;span class="n"&gt;petStoreClient&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;ValuesController&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IPetStoreClient&lt;/span&gt; &lt;span class="n"&gt;petStoreClient&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;petStoreClient&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;petStoreClient&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HttpGet&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ActionResult&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CancellationToken&lt;/span&gt; &lt;span class="n"&gt;ct&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;stu&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;petStoreClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetUserByNameAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Stu"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ct&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;stu&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Email&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You can see all of the &lt;a href="https://github.com/slang25/nswag-petstore-client"&gt;code here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>dotnetcore</category>
      <category>csharp</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Miscellaneous C# Async Tips</title>
      <dc:creator>Stuart Lang</dc:creator>
      <pubDate>Mon, 03 Dec 2018 07:50:29 +0000</pubDate>
      <link>https://dev.to/stuartblang/miscellaneous-c-async-tips-3o47</link>
      <guid>https://dev.to/stuartblang/miscellaneous-c-async-tips-3o47</guid>
      <description>&lt;p&gt;There are lots of great async tips out there, here a random few that I've collected over the past couple of years that I haven't seen much written about.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use Discards with &lt;code&gt;Task.Run&lt;/code&gt; for Fire and Forget
&lt;/h3&gt;

&lt;p&gt;This is a minor bit of guidance, but one of my favourites. If you are starting a &lt;code&gt;Task&lt;/code&gt; in a fire-and-forget manner with &lt;code&gt;Task.Run&lt;/code&gt;, other readers of the code might be thinking "did they forget to &lt;code&gt;await&lt;/code&gt; the returned task here?".&lt;/p&gt;

&lt;p&gt;You could make your intent explicit with a comment, but a very concise and clear way to indicate this was your intention is to use &lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/discards"&gt;the discard feature in C# 7.0&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;SomeBackgroundWork&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// Fire and forget&lt;/span&gt;

&lt;span class="c1"&gt;// becomes&lt;/span&gt;

&lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;SomeBackgroundWork&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Of course, comment if you need to clarify anything, but in this example, I think it makes sense to omit the comment as it leaves less noise.&lt;/p&gt;

&lt;h2&gt;
  
  
  Replace &lt;code&gt;Task.Factory.StartNew&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Task.Factory.StartNew&lt;/code&gt; was often used before &lt;code&gt;Task.Run&lt;/code&gt; was a thing, and &lt;code&gt;StartNew&lt;/code&gt; can be a bit misleading when you are dealing with async code as it represents the initial &lt;em&gt;synchronous&lt;/em&gt; part of an async delegate, due to their being no overload that takes a &lt;code&gt;Func&amp;lt;Task&amp;lt;T&amp;gt;&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Stephen Cleary even &lt;a href="https://blog.stephencleary.com/2013/08/startnew-is-dangerous.html"&gt;goes as far to say it is dangerous&lt;/a&gt;, and has very few valid use cases, including being able to start a &lt;code&gt;LongRunning&lt;/code&gt; task for work that will block in order to prevent blocking on your precious thread pool threads. Bar Arnon &lt;a href="http://blog.i3arnon.com/2015/07/02/task-run-long-running/"&gt;points out this almost never mixes well with async code&lt;/a&gt;. In short &lt;code&gt;StartNew&lt;/code&gt; is rarely useful, and importantly could cause confusion.&lt;/p&gt;

&lt;p&gt;My first tip is, where ever you see the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Factory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;StartNew&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/* Something */&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;Unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;to make it more familiar to other readers of the code, you can replace it with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/* Something */&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If you see usages without &lt;code&gt;Unwrap()&lt;/code&gt;, there's a chance it's not doing what you think it's doing. Or if you are using it to start a task with custom &lt;code&gt;TaskCreationOptions&lt;/code&gt;, be sure it's required for your scenario. To be clear, here is a rare scenario where it would make sense:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Factory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;StartNew&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Some blocking work you wouldn't want happening on your threadpool threads.&lt;/span&gt;
        &lt;span class="nf"&gt;DoSomething&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="n"&gt;TaskCreationOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LongRunning&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Async &amp;amp; Lazy
&lt;/h3&gt;

&lt;p&gt;One common place where people get caught out in migrating synchronous code to async is where they have lazy initiated properties or singletons, and it now needs to be initialized asynchronously. A great tool in your toolbelt in the sync world to deal with this is &lt;code&gt;Lazy&amp;lt;T&amp;gt;&lt;/code&gt;, however, how can we use this with async and Tasks?&lt;/p&gt;

&lt;p&gt;By default &lt;code&gt;Lazy&amp;lt;T&amp;gt;&lt;/code&gt; uses the setting &lt;code&gt;LazyThreadSafetyMode.ExecutionAndPublication&lt;/code&gt;, this means it's thread-safe, and if multiple concurrent threads try to access the value, only one triggers the creation, and the others all wait for the value to become available.&lt;/p&gt;

&lt;p&gt;What's nice is this is kind of how &lt;code&gt;Task&amp;lt;T&amp;gt;&lt;/code&gt; works with regards to awaiting. If one thread creates a &lt;code&gt;Task&lt;/code&gt; instance that is awaited by other threads before it completes, they wait for the value to become available, without additionally executing the same work. However we need a thread-safe way to create the &lt;code&gt;Task&lt;/code&gt; instance, so we can combine it with &lt;code&gt;Lazy&amp;lt;T&amp;gt;&lt;/code&gt; like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;Lazy&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_lazyAccessToken&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Lazy&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;RetrieveAccessTokenAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;AccessToken&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_lazyAccessToken&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I've written this verbosely to be clear, but we can reduce this by making the statement a lambda, eliding the await, and replacing the invocation of &lt;code&gt;RetrieveAccessTokenAsync&lt;/code&gt; with the method group like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;Lazy&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_lazyAccessToken&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Lazy&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;RetrieveAccessTokenAsync&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;AccessToken&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_lazyAccessToken&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Note that it's important to defer the accessing of &lt;code&gt;.Value&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We could encapsulate into a type like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;sealed&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AsyncLazy&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Lazy&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;AsyncLazy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Func&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;taskFactory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;taskFactory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Or we could use the great &lt;a href="https://github.com/Microsoft/vs-threading/"&gt;vs-threading&lt;/a&gt; library from Microsoft (if you can get over the VisualStudio namespace), which contains lots of well-polished async primitives such as &lt;code&gt;AsyncLazy&amp;lt;T&amp;gt;&lt;/code&gt; you would almost expect to come included with the framework and part of .NET Standard.&lt;/p&gt;

&lt;p&gt;Also, an honourable mention goes to &lt;a href="https://github.com/StephenCleary/AsyncEx/blob/daa22bf7721abd182201661cf7414e7d614ffde6/src/Nito.AsyncEx.Coordination/AsyncLazy.cs"&gt;AsyncLazy&lt;/a&gt; defined in &lt;code&gt;Nito.AsyncEx.Coordination&lt;/code&gt; by Stephen Cleary.&lt;/p&gt;

&lt;p&gt;An alternative strategy to &lt;code&gt;AsyncLazy&amp;lt;T&amp;gt;&lt;/code&gt; if you don't require it to be lazy, is to eagerly assign a field or property with a task in a constructor, which is started but not awaited, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ApiClient&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;ApiClient&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;AccessToken&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;RetrieveAccessTokenAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;AccessToken&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// here AccessToken is a hot Task, that may or may not be complete by the time it's first accessed&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Async &amp;amp; Lock
&lt;/h3&gt;

&lt;p&gt;Another thing that trips people up when migrating their synchronous code is dealing with &lt;code&gt;lock&lt;/code&gt; blocks, where async code cannot go. First I say, what are you trying to achieve? If it's thread-safe initialization of a resource or singleton, then use Lazy/AsyncLazy mentioned above, your code will likely be cleaner and express your intent better.&lt;/p&gt;

&lt;p&gt;If you do need a &lt;code&gt;lock&lt;/code&gt; block which contains async code, try using a &lt;code&gt;SemaphoreSlim&lt;/code&gt;. &lt;code&gt;SemaphoreSlim&lt;/code&gt; does a bit more than &lt;code&gt;Monitor&lt;/code&gt; and what you need for a &lt;code&gt;lock&lt;/code&gt; block, but you can use it in a way that gives you the same behaviour. By initializing the &lt;code&gt;SemaphoreSlim&lt;/code&gt; with an initial value of 1, and a maximum value of 1, we can use it to get thread-safe gated access to some region of code that guarantees exclusive execution.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;_semaphore&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;SemaphoreSlim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// initial: 1, max: 1  &lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;MyMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CancellationToken&lt;/span&gt; &lt;span class="n"&gt;cancellationToken&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_semaphore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WaitAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cancellationToken&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// the following line will only ever be called by one thread at any time&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;SomethingAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;finally&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_semaphore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Release&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;What's also cool is that &lt;code&gt;SemaphoreSlim&lt;/code&gt; has a synchronous &lt;code&gt;Wait&lt;/code&gt; method in addition to &lt;code&gt;WaitAsync&lt;/code&gt;, so we can use it in scenarios where we need both synchronous and asynchronous access (be careful of course).&lt;/p&gt;

&lt;p&gt;It may also be worth checking out &lt;code&gt;AsyncLock&lt;/code&gt; from &lt;code&gt;Nito.AsyncEx.Coordination&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That's it for now, a bit of a random assortment I know.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Thanks to Thomas Levesque for pointing out in the comments that &lt;code&gt;SemaphoreSlim&lt;/code&gt; differs from &lt;code&gt;Monitor&lt;/code&gt;/&lt;code&gt;lock&lt;/code&gt; because it is not reentrant. This means a lock has no issue being acquired from a thread that has already acquired it, whereas with a &lt;code&gt;SemaphoreSlim&lt;/code&gt; you would end up deadlocking yourself under the same scenario.&lt;/p&gt;

&lt;p&gt;Another caveat feedback by &lt;a href="https://disqus.com/by/odinserj/"&gt;odinserj&lt;/a&gt; in the comments is that on .NET Framework, a thread abort exception could leave the semaphore forever depleted, so it's not bulletproof.&lt;/p&gt;

</description>
      <category>csharp</category>
    </item>
    <item>
      <title>BigInteger to String in Any Base with F#</title>
      <dc:creator>Stuart Lang</dc:creator>
      <pubDate>Sat, 01 Dec 2018 23:19:09 +0000</pubDate>
      <link>https://dev.to/stuartblang/biginteger-to-string-in-any-base-with-f-3ma2</link>
      <guid>https://dev.to/stuartblang/biginteger-to-string-in-any-base-with-f-3ma2</guid>
      <description>&lt;p&gt;I spend a lot of time persuading people that F# is not about maths and finance, it's a great general purpose language that shines in many areas (such as domain modelling). However I've been playing around with some maths lately, and F# is my go-to for this, so here's a post.&lt;/p&gt;

&lt;p&gt;As the numbers we do arithmetic with get increasingly larger, the usual numeric types in .NET quickly fall short, with &lt;code&gt;Int32.MaxValue&lt;/code&gt; being &lt;code&gt;2147483647&lt;/code&gt;, and &lt;code&gt;Int64.MaxValue&lt;/code&gt; being &lt;code&gt;9223372036854775807&lt;/code&gt;. When we need to go beyond this we can use &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.numerics.biginteger?view=netstandard-2.0"&gt;&lt;code&gt;BigInteger&lt;/code&gt;&lt;/a&gt; aka &lt;code&gt;bigint&lt;/code&gt; (the &lt;a href="https://fsharpforfunandprofit.com/posts/type-abbreviations/"&gt;type abbreviation&lt;/a&gt; in F#) which can represent an arbitrarily large integer.&lt;/p&gt;

&lt;p&gt;I had the need to print a &lt;code&gt;bigint&lt;/code&gt; in any given base (not just decimal, binary, hexadecimal...), and to my surprise, there was nothing out of the box to do this.&lt;/p&gt;

&lt;h3&gt;
  
  
  The code
&lt;/h3&gt;

&lt;p&gt;First I want to turn a &lt;code&gt;bigint&lt;/code&gt; into a list of digits.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight fsharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// int -&amp;gt; bigint -&amp;gt; int list&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;bigintToDigits&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;rec&lt;/span&gt; &lt;span class="n"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="n"&gt;digits&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quotient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;remainder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bigint&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DivRem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bigint&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;quotient&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt;
        &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;zero&lt;/span&gt; &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="n"&gt;zero&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="nc"&gt;I&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;remainder&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="n"&gt;digits&lt;/span&gt;
        &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;_&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;loop&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="n"&gt;quotient&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;remainder&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="n"&gt;digits&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;loop&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="bp"&gt;[]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Things to note;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The inner function is recursive (given by the &lt;code&gt;rec&lt;/code&gt; keyword), and the outer function just kicks it off with the initial empty digit list. Here &lt;code&gt;b&lt;/code&gt; is the base (&lt;code&gt;base&lt;/code&gt; is a keyword, unfortunately).&lt;/li&gt;
&lt;li&gt;Recursion is often used in functional languages as an alternative to mutable state within loops, and in many cases can lead to a more natural expression of an algorithm/routine. Recursion in F# doesn't overflow the stack and is fast, provided it is tail call optimizable like in this case (i.e. the last thing the function does is call itself, or returns out).&lt;/li&gt;
&lt;li&gt;We divide by the base and take the remainder as the least significant digit, then we pass accumulated digits into the loop, along with the quotient and keep going until we get a quotient of &lt;code&gt;0&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;bigint.DivRem&lt;/code&gt; returns a quotient and a remainder &lt;code&gt;out&lt;/code&gt; parameter, with F# we can treat methods without parameters as if it returned a tuple of the result and the &lt;code&gt;out&lt;/code&gt; parameter.&lt;/li&gt;
&lt;li&gt;Usually, we could pattern match with &lt;code&gt;0&lt;/code&gt; as a literal, but because &lt;code&gt;0I&lt;/code&gt; (bigint zero) is a "non-primative literal", we aren't allowed to use it as a constant pattern. Hence the &lt;code&gt;when zero = 0I&lt;/code&gt; syntax.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;::&lt;/code&gt; is the cons operator, we can use it to construct F# lists, the part to the left is prepended to the part on the right.&lt;/li&gt;
&lt;li&gt;F# calls a spade a spade - &lt;code&gt;list&amp;lt;'a&amp;gt;&lt;/code&gt; is a linked list, while the C# &lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt; is type abbreviated in F# to what it really is, a &lt;code&gt;ResizeArray&lt;/code&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight fsharp"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="nc"&gt;ResizeArray&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;'&lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;Collections&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;Generic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;'&lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now we have a list of digits, let's have a function to convert it to a string (this only supports bases up to 16 at the moment).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight fsharp"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;digitsToString&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;source&lt;/span&gt;
    &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"X"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="nc"&gt;ToLowerInvariant&lt;/span&gt;&lt;span class="bp"&gt;()&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;concat&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Putting this together, if we want to print a &lt;code&gt;bigint&lt;/code&gt; in base 16, we do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight fsharp"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;printBigintAsHex&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;bigintToHex&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bigintToDigits&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;
    &lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;bigintToHex&lt;/span&gt; &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt;  &lt;span class="n"&gt;digitsToString&lt;/span&gt; &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"%s"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I couldn't find anything on Google or Stack Overflow to do this, so I thought I'd share it here so that it'll show up next time someone looks for it.&lt;/p&gt;

</description>
      <category>fsharp</category>
    </item>
    <item>
      <title>How to dotnet build and Target net4x on macOS</title>
      <dc:creator>Stuart Lang</dc:creator>
      <pubDate>Mon, 24 Sep 2018 19:01:37 +0000</pubDate>
      <link>https://dev.to/stuartblang/how-to-dotnet-build-and-target-net4x-on-macos-3h0h</link>
      <guid>https://dev.to/stuartblang/how-to-dotnet-build-and-target-net4x-on-macos-3h0h</guid>
      <description>&lt;p&gt;In &lt;a href="https://dev.to/stuartblang/net-framework-support-for-net-standard-20-5a4i-temp-slug-9523411"&gt;a previous post&lt;/a&gt;, I made a recommendation of additionally targeting &lt;code&gt;net461&lt;/code&gt; in addition to &lt;code&gt;netstandard2.0&lt;/code&gt; in certain scenarios, however one of the nice things about targeting &lt;code&gt;netstandard2.x&lt;/code&gt; is that on macOS you can install the .NET Core SDK, build it, and "it just works".&lt;/p&gt;

&lt;p&gt;With &lt;code&gt;net4x&lt;/code&gt; however, when you run &lt;code&gt;dotnet build&lt;/code&gt; you might see this error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error MSB3644: The reference assemblies for framework ".NETFramework,Version=v4.6.1" were not found.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And that makes a lot of sense because in order to compile for &lt;code&gt;net461&lt;/code&gt; in this case, we need the reference assemblies of that framework, these are dlls that are the same as the runtime assemblies, but just the signatures, no implementation. On Windows these are called "Targeting Packs" and you would have these ship with Visual Studio, or packaged via standalone installers called "Developer Packs".&lt;/p&gt;

&lt;p&gt;On macOS, there are 2 ways to reference these reference assemblies that I know of;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Using the mono reference assemblies
&lt;/h3&gt;

&lt;p&gt;If you have Visual Studio for Mac or Rider installed, then you probably already have this installed, and otherwise, it's a good idea to get the latest stable version installed &lt;a href="https://www.mono-project.com/download/stable/"&gt;from here&lt;/a&gt;. You will probably be able to find the reference assemblies located under version folders within &lt;code&gt;/Library/Frameworks/Mono.framework/Versions/Current/lib/mono&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now the MSBuild that comes with the .NET Core SDK needs to know where to find the reference assemblies. I found a &lt;a href="https://github.com/dotnet/sdk/issues/335#issuecomment-368669050"&gt;solution here&lt;/a&gt;, however, I'm not sure where it originates from (maybe it was from there?).&lt;/p&gt;

&lt;p&gt;You can include a file named &lt;code&gt;netfx.props&lt;/code&gt; with &lt;a href="https://github.com/Microsoft/visualfsharp/blob/24a432f03219b62fa647777a531bb7e70fa044e0/fcs/netfx.props"&gt;this content&lt;/a&gt;, and import it into your project like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;Project&lt;/span&gt; &lt;span class="na"&gt;Sdk=&lt;/span&gt;&lt;span class="s"&gt;"Microsoft.NET.Sdk"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;Import&lt;/span&gt; &lt;span class="na"&gt;Project=&lt;/span&gt;&lt;span class="s"&gt;"netfx.props"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;PropertyGroup&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Description&amp;gt;&lt;/span&gt;...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And now you are good to go!&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Obtain the reference assemblies via MyGet
&lt;/h3&gt;

&lt;p&gt;An alternative approach that doesn't require having mono installed is to obtain them via nuget, however, they are not available on nuget.org as of today, there is &lt;a href="https://github.com/dotnet/designs/pull/33"&gt;a GitHub issue&lt;/a&gt; that can be tracked regarding this. They currently exist on a MyGet feed (from version 4.5 and up). These are official Microsoft packages, &lt;a href="https://dotnet.myget.org/feed/dotnet-core/package/nuget/Microsoft.TargetingPack.NETFramework.v4.6.1"&gt;here's an example for 4.6.1&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;First, you need to add the feed like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight xml"&gt;&lt;code&gt;  &lt;span class="nt"&gt;&amp;lt;PropertyGroup&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;TargetFrameworks&amp;gt;&lt;/span&gt;net461;netstandard2.0&lt;span class="nt"&gt;&amp;lt;/TargetFrameworks&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;RestoreAdditionalProjectSources&amp;gt;&lt;/span&gt;
      https://dotnet.myget.org/F/dotnet-core/api/v3/index.json
    &lt;span class="nt"&gt;&amp;lt;/RestoreAdditionalProjectSources&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/PropertyGroup&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You may have also seen this done via &lt;code&gt;NuGet.config&lt;/code&gt; (which is just less cool), or you may have seen this using the &lt;code&gt;RestoreSources&lt;/code&gt; property, which would require you to append it to the existing source like this: &lt;code&gt;&amp;lt;RestoreSources&amp;gt;$(RestoreSources);...&amp;lt;/RestoreSources&amp;gt;&lt;/code&gt;&lt;br&gt;&lt;br&gt;
You can read more about that &lt;a href="https://github.com/NuGet/Home/wiki/%5BSpec%5D-NuGet-settings-in-MSBuild#project-properties"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now we can import the package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight xml"&gt;&lt;code&gt; &lt;span class="nt"&gt;&amp;lt;ItemGroup&lt;/span&gt; &lt;span class="na"&gt;Condition=&lt;/span&gt;&lt;span class="s"&gt;" '$(TargetFramework)' == 'net461' "&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;PackageReference&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"Microsoft.TargetingPack.NETFramework.v4.6.1"&lt;/span&gt;
                        &lt;span class="na"&gt;Version=&lt;/span&gt;&lt;span class="s"&gt;"1.0.1"&lt;/span&gt; &lt;span class="na"&gt;ExcludeAssets=&lt;/span&gt;&lt;span class="s"&gt;"All"&lt;/span&gt; &lt;span class="na"&gt;PrivateAssets=&lt;/span&gt;&lt;span class="s"&gt;"All"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/ItemGroup&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Finally, we need to point the &lt;code&gt;FrameworkPathOverride&lt;/code&gt; to the assemblies from this package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight xml"&gt;&lt;code&gt;  &lt;span class="nt"&gt;&amp;lt;PropertyGroup&lt;/span&gt; &lt;span class="na"&gt;Condition=&lt;/span&gt;&lt;span class="s"&gt;"'$(TargetFramework)'== 'net461'"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;FrameworkPathOverride&amp;gt;&lt;/span&gt;$(NuGetPackageRoot)microsoft.targetingpack.netframework.v4.6.1/1.0.1/lib/net461/&lt;span class="nt"&gt;&amp;lt;/FrameworkPathOverride&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/PropertyGroup&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;And that's it. There is always the option of using &lt;code&gt;msbuild&lt;/code&gt; shipped with mono too by running it just for the &lt;code&gt;net4x&lt;/code&gt; tfm, and using &lt;code&gt;dotnet build&lt;/code&gt; for other tfms, but where's the fun in that? Let me know if you have other ways of approaching this in the comments.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Displaying Images in iTerm from .NET Console Apps</title>
      <dc:creator>Stuart Lang</dc:creator>
      <pubDate>Sun, 02 Sep 2018 18:32:18 +0000</pubDate>
      <link>https://dev.to/stuartblang/displaying-images-in-iterm-from-net-console-apps-3i39</link>
      <guid>https://dev.to/stuartblang/displaying-images-in-iterm-from-net-console-apps-3i39</guid>
      <description>

&lt;p&gt;Now that dotnet global tools are a thing, we are seeing an explosion of cool new cross-platform command line apps being built with dotnet. A recent example of this is &lt;a href="https://github.com/DavidDeSloovere/giphy-cli"&gt;Giphy CLI&lt;/a&gt;, this is a tool to quickly get a gif url from giphy.com and markdown snippet ready for pasting.&lt;/p&gt;

&lt;p&gt;My favourite terminal when using my Mac is &lt;a href="https://iterm2.com/"&gt;iTerm2&lt;/a&gt;, it has lots of cool features, &lt;a href="https://iterm2.com/documentation-images.html"&gt;including the ability to display images right in the console&lt;/a&gt;! So I thought it would be great to add this feature to Giphy CLI, but first, how does it work?&lt;/p&gt;

&lt;h3&gt;
  
  
  Instructions from Docs
&lt;/h3&gt;

&lt;p&gt;iTerm2 extends the xterm protocol with a set of proprietary escape sequences. In general, the pattern is:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ESC ] 1337 ; key = value ^G&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Whitespace is shown here for ease of reading: in practice, no spaces should be used.&lt;/p&gt;

&lt;p&gt;For file transfer and inline images, the code is:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ESC ] 1337 ; File = [optional arguments] : base-64 encoded file contents ^G&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  .NET Implementation
&lt;/h3&gt;

&lt;p&gt;So to be honest, from mostly trial and error, I found that this is what you need to do from .NET:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"\u001B]1337"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;";File=;inline=1:"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Convert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToBase64String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;imageBytes&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"\u0007"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;where &lt;code&gt;imageBytes&lt;/code&gt; are the bytes of the image you want to display. You may also want to detect if you are running in iTerm in the first place and only run this code if this is the case. Thankfully iTerm sets an environment variable we can use, named &lt;code&gt;TERM_PROGRAM&lt;/code&gt;, which will have the value &lt;code&gt;iTerm.app&lt;/code&gt; in the case where it's running under iTerm. Let's do that:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetEnvironmentVariable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TERM_PROGRAM"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"iTerm.app"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"\u001B]1337"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;";File=;inline=1:"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Convert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToBase64String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;imageBytes&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"\u0007"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here is the result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--g2ikg3MF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://stu.dev/content/images/2018/09/giphy-animated-gif-1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--g2ikg3MF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://stu.dev/content/images/2018/09/giphy-animated-gif-1.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can &lt;a href="https://github.com/DavidDeSloovere/giphy-cli/pull/2/files"&gt;see this PR for a full working example&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks to David De Sloovere for building this cool little tool.&lt;/p&gt;


</description>
      <category>netcore</category>
    </item>
    <item>
      <title>.NET Framework Support for .NET Standard 2.0</title>
      <dc:creator>Stuart Lang</dc:creator>
      <pubDate>Tue, 28 Aug 2018 16:50:54 +0000</pubDate>
      <link>https://dev.to/stuartblang/net-framework-support-for-net-standard-20-5gkj</link>
      <guid>https://dev.to/stuartblang/net-framework-support-for-net-standard-20-5gkj</guid>
      <description>&lt;p&gt;When .NET Standard 2.0 was introduced, it wasn't plain sailing. .NET Standard 1.5 and 1.6 were already a thing, and they included APIs from .NET Frameworks higher than .NET Framework 4.6.1. Since .NET Standard releases should always be supersets of the previous releases, it naturally followed that .NET Standard 2.0 would only be supported in .NET Frameworks greater than or equal to 4.7.0, as Standard 1.5 included APIs from Framework 4.6.2, and Standard 1.6 included APIs from Framework 4.6.3.&lt;/p&gt;

&lt;p&gt;However Microsoft saw an opportunity to broaden the compatibility of .NET Standard 2.0 to include .NET Framework 4.6.1, this meant changing the existing Framework support levels for .NET Standard 1.5 and 1.6, as they had already been released. This was the direction taken due to the fact that the 4.6.1 runtime was so widely used it would have hindered the adoption and success of .NET Standard, and .NET Core as a result, had it been left out.&lt;/p&gt;

&lt;p&gt;Having .NET Framework 4.6.1 work with .NET Standard 2.0 packages was very ambitious given that it was already out there in use, support needed to be built retrospectively.&lt;/p&gt;

&lt;p&gt;While this mostly worked, in practice I found that there were many problems faced in writing .NET Standard libraries that would run on .NET Framework 4.6.1, and consuming them. Some of the issues I faced were to do with CI build agents not having the necessary versions of nuget and MSBuild to deal with .NET Standard 2.0 libraries, but the larger issues were around assembly binding redirects, and runtime issues, &lt;a href="https://github.com/dotnet/standard/issues/481"&gt;here is just a flavour&lt;/a&gt;. There were a number of issues that emerged over time and have become known issues.&lt;/p&gt;

&lt;p&gt;Because of all of the issues that I faced, and from other developers stories, the guidance I was giving people last year was to target both &lt;code&gt;netstandard2.0&lt;/code&gt; and &lt;code&gt;net461&lt;/code&gt; at the first sign of trouble if they were really keen on having just one target, or to target both from the beginning for a happy and peaceful life.&lt;/p&gt;

&lt;p&gt;Recently Immo Landwerth &lt;a href="https://twitter.com/terrajobst/status/1031999730320986112"&gt;has said in a tweet&lt;/a&gt; that making .NET Standard 2.0 work on .NET Framework 4.6.1 was a mistake, and that the documentation will be updated to reflect the new guidance. He &lt;a href="https://twitter.com/terrajobst/status/1032000874552250368"&gt;has clarified&lt;/a&gt; that it is nothing to do with missing APIs (which is the case for some largely unused APIs in 1.5 &amp;amp; 1.6) but more to do with other issues such as tooling. You can see just some of these issues discussed in &lt;a href="https://github.com/dotnet/standard/issues/481"&gt;this GitHub issue&lt;/a&gt;.&lt;/p&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--nlY8AsDX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/970581417422872576/XOQG6g70_normal.jpg" alt="Immo Landwerth profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Immo Landwerth
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        @terrajobst
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P4t6ys1m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      Sorry but we messed up. We tried to make .NET Framework 4.6.1 retroactively implement .NET Standard 2.0. This was a mistake as we don't have a time machine and there is a tail of bugs.&lt;br&gt;&lt;br&gt;If you want to consume .NET Standard 1.5+ from .NET Framework, I recommend to be on 4.7.2. &lt;a href="https://t.co/E7H2Ps9cLk"&gt;twitter.com/marcgravell/st…&lt;/a&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      20:21 PM - 21 Aug 2018
    &lt;/div&gt;

      &lt;div class="ltag__twitter-tweet__quote"&gt;
        &lt;div class="ltag__twitter-tweet__quote__header"&gt;
          &lt;span class="ltag__twitter-tweet__quote__header__name"&gt;
            Marc Gravell
          &lt;/span&gt;
          @marcgravell
        &lt;/div&gt;
        Sigh; another report of problems with System.Numerics.Vectors in a .net standard 2.0 lib running on net461 causing binding problems. Yay?
      &lt;/div&gt;

    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1031999730320986112" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-reply-action.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1031999730320986112" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-retweet-action.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      157
      &lt;a href="https://twitter.com/intent/like?tweet_id=1031999730320986112" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-like-action.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
      313
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


&lt;p&gt;There has been a recent drive to move to &lt;code&gt;netstandard2.0&lt;/code&gt; to get the benefits it brings to development time thanks to &lt;a href="https://twitter.com/davidfowl/status/1008453902058917888"&gt;this recent tweet&lt;/a&gt; from David Fowler, which is great advice, but many have opted to take this opportunity to remove &lt;code&gt;net461&lt;/code&gt; or lower, meaning that consumers that update now face some of these problems.&lt;/p&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZoY36T1d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/511247105722036224/VpxmKujV_normal.jpeg" alt="David Fowler profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        David Fowler
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        @davidfowl
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P4t6ys1m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      I know we said target The lowest netstandard but we really want everyone to re-baseline at  netstandard 2.0. At the very least add a netstandard 2.0 target. &lt;a href="https://twitter.com/hashtag/dotnetcore"&gt;&lt;/a&gt;&lt;a href="https://twitter.com/hashtag/dotnet"&gt;#dotnet&lt;/a&gt;core &lt;a href="https://twitter.com/hashtag/dotnet"&gt;#dotnet&lt;/a&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      20:58 PM - 17 Jun 2018
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1008453902058917888" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-reply-action.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1008453902058917888" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-retweet-action.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      69
      &lt;a href="https://twitter.com/intent/like?tweet_id=1008453902058917888" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-like-action.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
      148
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  Recommendations
&lt;/h2&gt;

&lt;p&gt;So my recommendation today for library authors that intend to build packages for multiple platforms, including running on &lt;code&gt;net461&lt;/code&gt; - &lt;code&gt;net471&lt;/code&gt;, is to target &lt;code&gt;netstandard2.0&lt;/code&gt; and the &lt;code&gt;net4x&lt;/code&gt; platform you want to support. .NET Framework 4.7.2 has been built with &lt;code&gt;netstandard2.0&lt;/code&gt; in mind, so it's at that point you can lose the separate target.&lt;/p&gt;

&lt;p&gt;If we want to quickly visualise this with the &lt;a href="https://docs.microsoft.com/en-us/dotnet/standard/net-standard#net-implementation-support"&gt;.NET Standard implementation support table&lt;/a&gt;, then here's what it looks like:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;.NET Standard&lt;/th&gt;
&lt;th&gt;2.0&lt;/th&gt;
&lt;th&gt;2.1&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;.NET Core&lt;/td&gt;
&lt;td&gt;2.0&lt;/td&gt;
&lt;td&gt;3.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;.NET Framework&lt;/td&gt;
&lt;td&gt;Feasible but problematic: 4.6.1&lt;br&gt; Works: 4.7.2&lt;/td&gt;
&lt;td&gt;TBC (Not 4.8)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If the "Feasible but problematic" part makes you feel uncomfortable, feel free to interpret that as "Does not work". Really it means get ready for possible pain, which is something that as a library author you don't want to unleash on your consumers.&lt;/p&gt;

&lt;p&gt;If you are that consumer that is experiencing these issues as a result of running .NET Standard packages on .NET Framework 4.6.1, you should prioritise upgrading to 4.7.2, this will really save you time and pain in the long run. If you aren't directly able to do this, apply pressure to those that are in control of this.&lt;/p&gt;

&lt;p&gt;Microsoft will be updating their documentation around this topic with official guidance, and I will be updating this post once that is released.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--g2Q0siTx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://stu.dev/content/images/2018/08/netstandard-tldr-1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--g2Q0siTx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://stu.dev/content/images/2018/08/netstandard-tldr-1.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>dotnetcore</category>
    </item>
    <item>
      <title>Pattern Matching F# Union Types in C# 7</title>
      <dc:creator>Stuart Lang</dc:creator>
      <pubDate>Fri, 27 Jul 2018 13:26:27 +0000</pubDate>
      <link>https://dev.to/stuartblang/pattern-matching-f-union-types-in-c-7-5cnm</link>
      <guid>https://dev.to/stuartblang/pattern-matching-f-union-types-in-c-7-5cnm</guid>
      <description>&lt;p&gt;Starting with C# 7.0, there is basic pattern matching support. I want to look at using this to interop with F# Discriminated Unions, and see what consuming F# code from C# could look like at it's best.&lt;/p&gt;

&lt;p&gt;Here is an example of an F# Discriminated Union (hereafter DU)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight fsharp"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="nc"&gt;Record&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nc"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nc"&gt;Age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="nc"&gt;Abc&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;A&lt;/span&gt;
    &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;B&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="n"&gt;double&lt;/span&gt;
    &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;C&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nc"&gt;Record&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;For those unfamiliar with DUs, the &lt;code&gt;Abc&lt;/code&gt; type defined above can be either &lt;code&gt;A&lt;/code&gt;, &lt;code&gt;B&lt;/code&gt;, or &lt;code&gt;C&lt;/code&gt; (and nothing else), and in the case of &lt;code&gt;A&lt;/code&gt; there is no "payload", with &lt;code&gt;B&lt;/code&gt; and &lt;code&gt;C&lt;/code&gt; there is a payload that comes with it.&lt;/p&gt;

&lt;p&gt;So given that this compiles down to a sealed class, and that the cases become classes, we can use the new type pattern in C# to match this with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;HandleAbc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Abc&lt;/span&gt; &lt;span class="n"&gt;abc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;abc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;Abc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"B"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;Abc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;There are some things to notice here:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. It's really nice
&lt;/h3&gt;

&lt;p&gt;The code here is clean I'd say, we are matching on type and can either ignore the result of the cast using &lt;code&gt;_&lt;/code&gt; or we can take it as a named variable (like with &lt;code&gt;c&lt;/code&gt; in this example).&lt;/p&gt;

&lt;h3&gt;
  
  
  2. We don't get the safety we have in F
&lt;/h3&gt;

&lt;p&gt;In F#, when handling DUs the compiler ensure that we have handled all cases, in C#, these safety checks aren't enforced.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. What about case &lt;code&gt;A&lt;/code&gt;!
&lt;/h3&gt;

&lt;p&gt;Yeah, so this is where it's not perfect. The F# compiler does generate a type for case &lt;code&gt;A&lt;/code&gt; however it is marked as internal and therefore is not accessible for us to match against, however, there are a few options, I'll let you pick which is your favourite:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;HandleAbc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Abc&lt;/span&gt; &lt;span class="n"&gt;abc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;abc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Option 1:&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="n"&gt;when&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsA&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"A"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="c1"&gt;// Option 2:&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="n"&gt;when&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;Abc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"A"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;abc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Tag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Option 3:&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;abc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"A"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Let me know in the comments what your preference is, or is there a better option?&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>fsharp</category>
    </item>
    <item>
      <title>IAsyncEnumerable&lt;T&gt; - An Introduction</title>
      <dc:creator>Stuart Lang</dc:creator>
      <pubDate>Thu, 14 Jun 2018 14:56:13 +0000</pubDate>
      <link>https://dev.to/stuartblang/iasyncenumerablet---an-introduction-g99</link>
      <guid>https://dev.to/stuartblang/iasyncenumerablet---an-introduction-g99</guid>
      <description>&lt;h3&gt;
  
  
  The problem
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetUsers&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;allResults&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;nextUrl&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://account.zendesk.com/api/v2/users.json"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nextUrl&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nextUrl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadAsAsync&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;UsersListResponse&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
        &lt;span class="n"&gt;allResults&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Users&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;nextUrl&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NextPage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="c1"&gt;// eg "https://account.zendesk.com/api/v2/users.json?page=2"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;allResults&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Take a look at the above code, you may have run into this familiar issue yourself. We'd like to represent the pageable results of this HTTP API in our types, while still be asynchronous.&lt;/p&gt;

&lt;p&gt;Traditionally there would be 4 ways to approach this;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Block on the async code with &lt;code&gt;.Result&lt;/code&gt;/&lt;code&gt;.GetAwaiter().GetResult()&lt;/code&gt; or &lt;code&gt;.Wait()&lt;/code&gt;. This is &lt;a href="https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html"&gt;not a good idea&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;The above approach of awaiting each asynchronous task, but doing it all eagerly and returning the complete results in a materialised collection. This defeats the purpose of this paging API, and more generally we lose the laziness of the problem we are trying to model.&lt;/li&gt;
&lt;li&gt;We flip the return type to &lt;code&gt;IEnumerable&amp;lt;Task&amp;lt;User&amp;gt;&amp;gt;&lt;/code&gt;. This would require that we trust any consumers of this code to await the result of each task after every enumeration. There are ways to enforce this at runtime, and throw an exception if it's not consumed correctly, however, this ultimately is a misleading type, and the shape of the type doesn't communicate its hidden constraints.&lt;/li&gt;
&lt;li&gt;We don't try returning a single type such as &lt;code&gt;Task&amp;lt;IEnumerable&amp;lt;T&amp;gt;&amp;gt;&lt;/code&gt; and we model it ourselves. This can be a good idea, but we lose the benefits of having a familiar type to work with.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Well, it's about time we adopted a new type and end this madness. That's what &lt;code&gt;IAsyncEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; is for.&lt;/p&gt;

&lt;h3&gt;
  
  
  About Ix.Async
&lt;/h3&gt;

&lt;p&gt;Currently &lt;code&gt;IAsyncEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; is a concept which exists in a few places, with no singular definition. The version I will be using today lives in the &lt;a href="https://github.com/dotnet/reactive"&gt;Reactive Extensions repo&lt;/a&gt;, in &lt;a href="https://github.com/dotnet/reactive/tree/IxAsyncCSharp8/Ix.NET/Source"&gt;a fork&lt;/a&gt; that is based on &lt;a href="https://github.com/dotnet/csharplang/blob/9d86668fcd915e1d3ef7634551d52e4d22c0631a/proposals/async-streams.md"&gt;the latest C# 8.0 proposal&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Reactive Extensions (Rx) is the home of Observable implementation and extensions, it is also home to a sibling project named Interactive Extensions (Ix for short). Rx has lots of extensions and tools for composing pushed based sequences, and Ix is very similar but for pull-based sequences (&lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt;). The part I am interested in for this post is the async part, which I'll be referring to as Ix.Async, this is shipped in its own nuget package, and I will generally be referring to the &lt;code&gt;IAsyncEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; definition that lives here (although this will map trivially to other implementations).&lt;/p&gt;

&lt;p&gt;In the near future, C# 8.0 will introduce Async Streams (I prefer the term Sequence, as &lt;code&gt;Stream&lt;/code&gt; is already a different .NET concept) as a language feature, and there will be a new definition of &lt;code&gt;IAsyncEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; it will work with, but that doesn't stop us using Ix.Async today, either using the current definition which slightly differs from the C# 8.0 proposal or building the fork with the latest definition in.&lt;/p&gt;

&lt;h3&gt;
  
  
  Definition
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IAsyncEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;IAsyncEnumerator&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetAsyncEnumerator&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IAsyncEnumerator&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IAsyncDisposable&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;Current&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;ValueTask&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;MoveNextAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IAsyncDisposable&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ValueTask&lt;/span&gt; &lt;span class="nf"&gt;DisposeAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is the definition of &lt;code&gt;IAsyncEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; from the C# 8.0 proposal, it should look very familiar, it is just &lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; with an async &lt;code&gt;MoveNext&lt;/code&gt; method, as you might expect.&lt;br&gt;&lt;br&gt;
 &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gm1ko14N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://stu.dev/content/images/2018/06/async-enum12.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gm1ko14N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://stu.dev/content/images/2018/06/async-enum12.png" alt="async-enum12"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
We can now see the relationship with &lt;code&gt;IObservable&amp;lt;T&amp;gt;&lt;/code&gt; and &lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Being in this familiar family means that we don't have to learn new concepts to start consuming and composing operations over this type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;IAsyncEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Bar&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;ConvertGoodFoosToBars&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IAsyncEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsGood&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Bar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFoo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;These extension methods are immediately understandable to us and are ubiquitous in C# already.&lt;/p&gt;

&lt;h3&gt;
  
  
  Producing sequences
&lt;/h3&gt;

&lt;p&gt;All of this would be pretty academic if we couldn't generate sequences to be consumed. Today there are a few options.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Implement the &lt;code&gt;IAsyncEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; and &lt;code&gt;IAsyncEnumerator&amp;lt;T&amp;gt;&lt;/code&gt; interfaces directly
&lt;/h4&gt;

&lt;p&gt;You can do this, and for performance critical code, this might be the most suitable approach.&lt;/p&gt;

&lt;p&gt;It does require a fair bit of boilerplate code, however, so here is a starting point:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// A starting point for your own IAsyncEnumerable extensions&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AsyncEnumerableExtensions&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;IAsyncEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;MyExtensionMethod&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;IAsyncEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;MyAsyncEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;MyAsyncEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IAsyncEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IAsyncEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;enumerable&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="nf"&gt;MyAsyncEnumerable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IAsyncEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;enumerable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enumerable&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;enumerable&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;IAsyncEnumerator&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetAsyncEnumerator&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;MyAsyncEnumerator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;enumerable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetAsyncEnumerator&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;MyAsyncEnumerator&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IAsyncEnumerator&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IAsyncEnumerator&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;enumerator&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="nf"&gt;MyAsyncEnumerator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IAsyncEnumerator&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;enumerator&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enumerator&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;enumerator&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;ValueTask&lt;/span&gt; &lt;span class="nf"&gt;DisposeAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;enumerator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DisposeAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;Current&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;enumerator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Current&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;ValueTask&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;MoveNextAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;enumerator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;MoveNextAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  2. Use the static helper methods in Ix.NET
&lt;/h4&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;IAsyncEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GenerateWithIx&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;AsyncEnumerable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateEnumerable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; 
        &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CancellationToken&lt;/span&gt; &lt;span class="n"&gt;ct&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nf"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TimeSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromSeconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
                &lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="p"&gt;++;&lt;/span&gt; 
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
            &lt;span class="p"&gt;}&lt;/span&gt; 

            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;AsyncEnumerable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateEnumerator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; 
                &lt;span class="n"&gt;moveNext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;dispose&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; 
            &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  3. Use CXuesong.AsyncEnumerableExtensions
&lt;/h4&gt;

&lt;p&gt;I wanted to build something like this myself, and then &lt;a href="https://github.com/CXuesong/AsyncEnumerableExtensions"&gt;I found this library&lt;/a&gt;, so I don't need to! Credit to &lt;a href="https://github.com/CXuesong"&gt;Chen&lt;/a&gt;, this is a great library.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// using CXuesong.AsyncEnumerableExtensions &lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;Generator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IAsyncEnumerableSink&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;sink&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TimeSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromSeconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;sink&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;YieldAndWait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;AsyncEnumerableFactory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FromAsyncGenerator&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;Generator&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This library offers a very nice and simple way to express sequences. You build an async function that takes an &lt;code&gt;IAsyncEnumberableSink&amp;lt;T&amp;gt;&lt;/code&gt; (defined by the library) and returns a &lt;code&gt;Task&lt;/code&gt;. Now you can do your awaits, but when you want to yield an item to the sequence, you call &lt;code&gt;sink.YieldAndWait(value)&lt;/code&gt; where &lt;code&gt;sink&lt;/code&gt; is that parameter.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Coming soon to a C# 8.0 near you
&lt;/h4&gt;

&lt;p&gt;Today you cannot use the &lt;code&gt;async&lt;/code&gt; keyword and iterator methods together, so having an async iterator method would require a new language feature. Well, good news, it's in the works, &lt;a href="https://github.com/dotnet/csharplang/blob/master/proposals/async-streams.md"&gt;take a sneak peek here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here is a snippet showing what it could look like.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;IAsyncEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Mylterator&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;finally&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;200&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"finally"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Consuming sequencing
&lt;/h3&gt;

&lt;p&gt;We can produce sequences, but that won't be much use to us if we cannot consume them.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. ForEachAsync
&lt;/h4&gt;

&lt;p&gt;Just like the &lt;code&gt;.ForEach(...)&lt;/code&gt; extension method on &lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt;, we have &lt;code&gt;.ForEachAsync(...)&lt;/code&gt; from Ix.Async, this lets us do work on each item, and gives us a &lt;code&gt;Task&lt;/code&gt; to await to drive the whole chain of pull-based work.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;seq&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ForEachAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Unfortunately, dogmatism fails here, &lt;code&gt;ForEachAsync&lt;/code&gt; is suffixed with &lt;code&gt;Async&lt;/code&gt; because it returns a &lt;code&gt;Task&lt;/code&gt; and operates asynchronously, however, the delegate it takes is synchronous, this led me to build a method that can take an async delegate and name it &lt;code&gt;ForEachAsyncButActuallyAsync&lt;/code&gt;. 🤦&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;seq&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ForEachAsyncButActuallyAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  2. C# 8.0 foreach
&lt;/h4&gt;

&lt;p&gt;Again, we have language support on the way. Here's what it would look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;asyncSequence&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;GetMyAsyncSequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cancellationToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ct&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;asyncSequence&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Design Decisions
&lt;/h3&gt;

&lt;p&gt;One of the problems that have meant that we've had to wait so long a first class &lt;code&gt;IAsyncEnumberable&amp;lt;T&amp;gt;&lt;/code&gt; and language features is because there are many design decisions that need answering, for example;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does &lt;code&gt;IAsyncEnumerator&amp;lt;T&amp;gt;&lt;/code&gt; implement &lt;code&gt;IDisposable&lt;/code&gt; or a new async version (&lt;code&gt;IAsyncDisposable&lt;/code&gt;)? &lt;strong&gt;Update&lt;/strong&gt; &lt;code&gt;IAsyncDisposable&lt;/code&gt; it is!&lt;/li&gt;
&lt;li&gt;If there is going to be an &lt;code&gt;IAsyncDisposable&lt;/code&gt;, should the language support the &lt;code&gt;using&lt;/code&gt; syntax for it?&lt;/li&gt;
&lt;li&gt;Does the &lt;code&gt;CancellationToken&lt;/code&gt; get passed into &lt;code&gt;MoveNext&lt;/code&gt; each move or &lt;code&gt;GetEnumerator&lt;/code&gt; once? &lt;strong&gt;Update&lt;/strong&gt; &lt;code&gt;CancellationToken&lt;/code&gt;s are not going to be handled by syntax, so you should flow it into the &lt;code&gt;IAsyncEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; types yourself.&lt;/li&gt;
&lt;li&gt;Should it be &lt;code&gt;MoveNext&lt;/code&gt;, or &lt;code&gt;MoveNextAsync&lt;/code&gt;? &lt;strong&gt;Update&lt;/strong&gt; &lt;code&gt;MoveNextAsync&lt;/code&gt; wins!&lt;/li&gt;
&lt;li&gt;Should &lt;code&gt;MoveNextAsync&lt;/code&gt; return a &lt;code&gt;Task&amp;lt;bool&amp;gt;&lt;/code&gt; or a &lt;code&gt;ValueTask&amp;lt;bool&amp;gt;&lt;/code&gt;? &lt;strong&gt;Update&lt;/strong&gt; &lt;code&gt;ValueTask&amp;lt;bool&amp;gt;&lt;/code&gt; has it!&lt;/li&gt;
&lt;li&gt;In the foreach syntax, where does the &lt;code&gt;await&lt;/code&gt; modifier go? Outside the brackets? (Yes, of course, what sort of monster do you take me for?)&lt;/li&gt;
&lt;li&gt;In the foreach syntax, how do you do the equivalent of &lt;code&gt;.ConfigureAwait(false)&lt;/code&gt;? &lt;strong&gt;Update&lt;/strong&gt; &lt;a href="https://github.com/dotnet/corefx/issues/32684#issue-367616580"&gt;like this&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Will the foreach syntax look for the type, or the pattern? &lt;code&gt;await&lt;/code&gt; doesn't just apply to &lt;code&gt;Task&lt;/code&gt; for example.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and that's just what comes immediately to mind, the more you think, the more you uncover.&lt;/p&gt;

&lt;h3&gt;
  
  
  Who is using it today?
&lt;/h3&gt;

&lt;p&gt;There are a couple of large projects using this today:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Entity Framework Core - Currently using an internal definition, but &lt;a href="https://github.com/aspnet/EntityFrameworkCore/issues/11866#issuecomment-385753917"&gt;there is talk&lt;/a&gt; of plans to use whatever comes in C# 8.&lt;/li&gt;
&lt;li&gt;Google Cloud Platform Libraries - This one was a bit of a surprise to me. If you install any Google Cloud package, it will reference their Core package, which uses and references Ix.Async. One of the members of the team that builds this is (the) Jon Skeet, so that's quite an endorsement!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stay tuned, there is more to come on this topic.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnetcore</category>
    </item>
    <item>
      <title>Adding AssemblyMetadataAttribute using new SDK project, with MSBuild</title>
      <dc:creator>Stuart Lang</dc:creator>
      <pubDate>Mon, 26 Mar 2018 19:20:36 +0000</pubDate>
      <link>https://dev.to/stuartblang/adding-assemblymetadataattribute-using-new-sdk-project-with-msbuild-2akl</link>
      <guid>https://dev.to/stuartblang/adding-assemblymetadataattribute-using-new-sdk-project-with-msbuild-2akl</guid>
      <description>&lt;p&gt;Now that we have the new project system, and we can define common assembly info in our &lt;code&gt;.csproj&lt;/code&gt;, we can say good-bye to &lt;code&gt;AssemblyInfo.cs&lt;/code&gt;, well, I still see these left around for general assembly attributes.&lt;/p&gt;

&lt;p&gt;For example it is quite common to see an &lt;code&gt;InternalsVisibileTo.cs&lt;/code&gt; file these days, instead of &lt;code&gt;AssemblyInfo.cs&lt;/code&gt;, &lt;a href="https://github.com/aspnet/EntityFrameworkCore/blob/cfed64d50977fc7c85267ddaab0aa96d834776cd/src/EFCore/Properties/InternalsVisibleTo.cs"&gt;see here for an example&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;However what if you want to add your own assembly attribute with a value you want to pass in as an MSBuild property? For example, an &lt;code&gt;AssemblyMetadataAttribute&lt;/code&gt; that contains a git commit hash?&lt;/p&gt;

&lt;p&gt;Well, we are in luck, there is an &lt;code&gt;AssemblyAttribute&lt;/code&gt; item we can add to our ItemGroup! If we had a property named &lt;code&gt;CommitHash&lt;/code&gt; we could write the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;AssemblyAttribute&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"System.Reflection.AssemblyMetadataAttribute"&lt;/span&gt; &lt;span class="na"&gt;Condition=&lt;/span&gt;&lt;span class="s"&gt;"$(CommitHash) != ''"&lt;/span&gt; &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;_Parameter1&amp;gt;&lt;/span&gt;CommitHash&lt;span class="nt"&gt;&amp;lt;/_Parameter1&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;_Parameter2&amp;gt;&lt;/span&gt;$(CommitHash)&lt;span class="nt"&gt;&amp;lt;/_Parameter2&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/AssemblyAttribute&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Great! One last thing, we need to say when this is going to happen, and that is before &lt;code&gt;CoreGenerateAssemblyInfo&lt;/code&gt;, so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;Target&lt;/span&gt; &lt;span class="na"&gt;Name=&lt;/span&gt;&lt;span class="s"&gt;"AddGitMetadaAssemblyAttributes"&lt;/span&gt;
          &lt;span class="na"&gt;BeforeTargets=&lt;/span&gt;&lt;span class="s"&gt;"CoreGenerateAssemblyInfo"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ItemGroup&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;AssemblyAttribute&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"System.Reflection.AssemblyMetadataAttribute"&lt;/span&gt; &lt;span class="na"&gt;Condition=&lt;/span&gt;&lt;span class="s"&gt;"$(CommitHash) != ''"&lt;/span&gt; &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;_Parameter1&amp;gt;&lt;/span&gt;CommitHash&lt;span class="nt"&gt;&amp;lt;/_Parameter1&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;_Parameter2&amp;gt;&lt;/span&gt;$(CommitHash)&lt;span class="nt"&gt;&amp;lt;/_Parameter2&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/AssemblyAttribute&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/ItemGroup&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/Target&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Cool. But wait! It doesn't always work. Sometimes when I do a build, the value doesn't change. What gives?&lt;/p&gt;

&lt;p&gt;So it turns out in .NET SDK 2 and up, there are lots of measures to improve performance, one of which is the &lt;code&gt;&amp;lt;AssemblyName&amp;gt;.AssemblyInfoInputs.cache&lt;/code&gt; file, which appears in the &lt;code&gt;obj&lt;/code&gt; folder, and just contains a hash of the &lt;code&gt;AssemblyInfo&lt;/code&gt; inputs as you'd expect.&lt;/p&gt;

&lt;p&gt;The hash is calculated internally only by the &lt;code&gt;_Parameter1&lt;/code&gt; values, so in our example where we put the varying data in &lt;code&gt;_Parameter2&lt;/code&gt;, this doesn't bust the cache. We can see the logic for this &lt;a href="https://github.com/dotnet/sdk/blob/v2.1.4/src/Tasks/Microsoft.NET.Build.Tasks/build/Microsoft.NET.GenerateAssemblyInfo.targets#L98-L100"&gt;here in &lt;code&gt;CreateGeneratedAssemblyInfoInputsCacheFile&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As a hacky workaround, we can temporarily add our values to &lt;code&gt;_Parameter1&lt;/code&gt; then remove them after the hash is generated. Like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;Target&lt;/span&gt; &lt;span class="na"&gt;Name=&lt;/span&gt;&lt;span class="s"&gt;"GitMetadataAssemblyInfoCacheFileFix"&lt;/span&gt;
        &lt;span class="na"&gt;BeforeTargets=&lt;/span&gt;&lt;span class="s"&gt;"CreateGeneratedAssemblyInfoInputsCacheFile"&lt;/span&gt; &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ItemGroup&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;AssemblyAttribute&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"TemporaryAdditionalHashItem"&lt;/span&gt; &lt;span class="na"&gt;Condition=&lt;/span&gt;&lt;span class="s"&gt;" $(CommitHash) != '' "&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;_Parameter1&amp;gt;&lt;/span&gt;$(CommitHash)&lt;span class="nt"&gt;&amp;lt;/_Parameter1&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/AssemblyAttribute&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/ItemGroup&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/Target&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;Target&lt;/span&gt; &lt;span class="na"&gt;Name=&lt;/span&gt;&lt;span class="s"&gt;"CleanupTemporaryAdditionalHashItem"&lt;/span&gt;
  &lt;span class="na"&gt;AfterTargets=&lt;/span&gt;&lt;span class="s"&gt;"CreateGeneratedAssemblyInfoInputsCacheFile;AddGitMetadaAssemblyAttributes"&lt;/span&gt; &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ItemGroup&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;AssemblyAttribute&lt;/span&gt; &lt;span class="na"&gt;Remove=&lt;/span&gt;&lt;span class="s"&gt;"TemporaryAdditionalHashItem"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/ItemGroup&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/Target&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now we recompile whenever there is a change to our added value. For the end result, &lt;a href="https://github.com/justeat/httpclient-interception/blob/2a7cca38244435ec4065b2030748a4a876759e2d/Directory.Build.targets#L9-L48"&gt;see here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;UPDATE: In the upcoming SDK at the time of writing (2.1.300), this hack is no longer required as @natemcmaster &lt;a href="https://github.com/dotnet/sdk/commit/73fb22a07091585380ead0bcbcdc38839a0266e8#diff-5b286bd8dee67543f08738e5605f0d3fR99"&gt;has fixed it here&lt;/a&gt;. Hurray!&lt;/p&gt;

</description>
      <category>msbuild</category>
      <category>dotnetcore</category>
    </item>
  </channel>
</rss>
