<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Jeremy Burman Blog</title>
  <id>https://jbminiblog.azurewebsites.net/</id>
  <subtitle>My ramblings in software and technology</subtitle>
  <generator uri="https://github.com/madskristensen/Miniblog.Core" version="1.0">Miniblog.Core</generator>
  <updated>2020-01-23T21:05:01Z</updated>
  <entry>
    <id>https://jbminiblog.azurewebsites.net/blog/host-worker-service-on-netframework/</id>
    <title>Hosted Worker Service on .NET Framework</title>
    <updated>2020-01-23T21:23:01Z</updated>
    <published>2020-01-23T21:05:01Z</published>
    <link href="https://jbminiblog.azurewebsites.net/blog/host-worker-service-on-netframework/" />
    <author>
      <name>test@example.com</name>
      <email>Jeremy Burman</email>
    </author>
    <category term=".net services" />
    <content type="html">&lt;p&gt;One of the nifty new templates for .NET Core will spit out a console app that runs a "Hosted" worker service. That is, code that runs in the background and takes advantage of all the new configuration and dependency injection APIs that were originally introduced along with ASP.NET Core. This is all documented over on &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services"&gt;docs.microsoft.com&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;However, if there is a need for it, it is still possible to setup a .NET Framework application that takes advantage of all of the same APIs and hosting model. (Note: the &lt;a href="https://github.com/jburman/blog-content/tree/master/NetFrameworkWorker"&gt;full working sample&lt;/a&gt; for this is posted on my Github repo).&lt;/p&gt;
&lt;p&gt;The first thing to do is, to create a regular ol' .NET Framework Console app. Then add in the following Nugets (I also like to go ahead and convert my project to use Package References and tidy things up a bit):&lt;/p&gt;
&lt;pre&gt;Install-Package Microsoft.Extensions.Configuration.UserSecrets&lt;br /&gt;&lt;br /&gt;Install-Package Microsoft.Extensions.Hosting&lt;br /&gt;&lt;br /&gt;Install-Package Microsoft.Extensions.Hosting.WindowsServices&lt;/pre&gt;
&lt;p&gt;The WindowsService package is optional, but if you're planning on running your worker service as a Windows Service then you'll have to bring that in as well.&lt;/p&gt;
&lt;p&gt;Next, let's go ahead an create a Worker class. The example doesn't do anything besides print a message every time it runs, but it also demonstrates that we'll be able to have the hosting service inject both an ILogger and an IConfiguration instance.&lt;/p&gt;
&lt;pre class="language-csharp"&gt;&lt;code&gt;public class Worker : BackgroundService
{
    private readonly ILogger&amp;lt;Worker&amp;gt; _logger;
    private readonly int _timeout;

    public Worker(ILogger&amp;lt;Worker&amp;gt; logger, IConfiguration config)
    {
        _logger = logger;
        _timeout = config.GetValue("WorkerTimeout", 5000);
    }

    protected async override Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while(!stoppingToken.IsCancellationRequested)
        {
            _logger.LogInformation("Executing Worker at {time}", DateTimeOffset.Now);

            await Task.Delay(_timeout, stoppingToken);
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, wire up the Host Builder in Program.cs. The important part is the call to AddHostedService&amp;lt;Worker&amp;gt; which is what wires up service host to our Worker class.&amp;nbsp;&lt;/p&gt;
&lt;pre class="language-csharp"&gt;&lt;code&gt;class Program
{
    static void Main(string[] args) =&amp;gt;
        CreateHostBuilder(args).Build().Run();

    public static IHostBuilder CreateHostBuilder(string[] args) =&amp;gt;
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration(configBuilder =&amp;gt; configBuilder.AddJsonFile("appsettings.json"))
            .UseWindowsService()
            .ConfigureServices((hostContext, services) =&amp;gt;
            {
                services.AddHostedService&amp;lt;Worker&amp;gt;();
            });
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are two other optional pieces that I added as examples.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The call to ConfigureAppConfiguration is used to load config settings from appsettings.json&lt;/li&gt;
&lt;li&gt;The call to .UseWindowsService() - again, if you're not going to host as a Windows Service, then that call can be removed.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And that's all there is to it! Of course, you can add in other extensions supported by the Hosting API's, e.g. other types of configuration providers, secrets, different logging etc.&amp;nbsp;&lt;/p&gt;</content>
  </entry>
  <entry>
    <id>https://jbminiblog.azurewebsites.net/blog/get-started-with-cryptocurrency-on-windows–part-2/</id>
    <title>Get Started with Cryptocurrency on Windows–Part 2</title>
    <updated>2017-12-20T04:09:51Z</updated>
    <published>2017-12-20T04:03:45Z</published>
    <link href="https://jbminiblog.azurewebsites.net/blog/get-started-with-cryptocurrency-on-windows–part-2/" />
    <author>
      <name>test@example.com</name>
      <email>Jeremy Burman</email>
    </author>
    <category term="cryptocurrency" />
    <content type="html">&lt;p&gt;In my &lt;a href="https://blog.jeremyburman.com/blog/get-started-with-a-cryptocurrency-on-windows-%E2%80%93-part-1/"&gt;previous post&lt;/a&gt;, I briefly described the tools that I use on Windows 10 for managing cryptocurrency (Litecoin specifically) and the steps needed to get going. In this post I’ll go into a bit more detail on how to actually complete the steps. Please refer to the end of this post for a list links for reference.&lt;/p&gt;  &lt;p&gt;The first step will be to download both the KeePass and Electrum-LTC programs. While optional, I highly recommend taking the time to verify the programs as well and establish the habit going forward. While not completely bullet proof (you’ll at least have to trust the site that you download the verification keys from), it will prevent you from accidentally using a version of the program that has been altered by a third party.&lt;/p&gt;  &lt;p&gt;To perform the verification of the downloaded programs, I use the GPG tooling in Linux. Alternatively, you could install Gpg4win; however, since Windows 10 has new support for true Linux distributions why not go directly to the source? To do so, you will need to first enable the Windows Subsystem for Linux (see the link at the end of this document or search how to in your favorite search engine.) Once WSL is enabled, visit the Windows Store and pick a distribution of Linux (I use Ubuntu, but there is Suse and others.) Once installed, launch the Bash command line shell.&lt;/p&gt;    &lt;h3&gt;&lt;font color="#4f81bd"&gt;Optional Step – Mounting a Removable Drive in WSL&lt;/font&gt;&lt;/h3&gt;  &lt;p&gt;If you are doing everything on an internal hard drive, then this next step can be skipped. In my case, I have a MicroSD card slotted into my Surface Pro and encrypted with BitLocker. WSL does not automatically mount a removal drive so this needs to be done manually. For example, if the MicroSD is mounted to drive letter D: in Windows then the following commands need to be run the mount it in WSL.&lt;/p&gt;  &lt;pre&gt;&lt;code&gt;$sudo mkdir /mnt/d&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then, to mount the drive (and again on subsequent Bash sessions):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ sudo mount -t drvfs D: /mnt/d&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When I’m finished, I can unmount it with.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ sudo umount /mnt/d&lt;/code&gt;&lt;/pre&gt;



&lt;h3&gt;Download and Verify KeePass&lt;/h3&gt;

&lt;p&gt;I will be keeping all of my downloaded files in D:\software (so in WSL that will be /mnt/d/software)&lt;/p&gt;

&lt;p&gt;Start by &lt;a href="https://keepass.info/download.html" target="_blank"&gt;downloading the latest version&lt;/a&gt; of KeePass. I prefer the Portable version so as to keep my system cleaner (it simply runs out of a folder and does not need to modify the Windows Registry etc.) Next, from the &lt;a href="https://keepass.info/integrity_sig.html" target="_blank"&gt;signatures page&lt;/a&gt;, download the PGP .asc file corresponding to the version of the program that you downloaded and place it in the same folder as the downloaded program file. For example, if you downloaded the portable version KeePass-2.37.zip then also download KeePass-2.37.zip.asc. The other piece of information that you need off of the signatures page is the Key ID of the program signer (see screen shot below).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.jeremyburman.com/posts/files/KeePassASC_636493394231262584.png"&gt;&lt;img title="KeePassASC" style="display: inline; background-image: none;" border="0" alt="KeePassASC" src="https://blog.jeremyburman.com/posts/files/KeePassASC_thumb_636493394237312726.png" width="677" height="495" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Over in the Bash window, run the following command (make sure you grab the actual Key ID off of the page when you run it)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ gpg --keyserver pool.sks-keyservers.net --recv-keys &amp;lt;keyIDvalue&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Below is an example with output.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.jeremyburman.com/posts/files/image_636493394239673880.png"&gt;&lt;img title="image" style="display: inline; background-image: none;" border="0" alt="image" src="https://blog.jeremyburman.com/posts/files/image_thumb_636493394243013616.png" width="678" height="108" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the key has been imported to your local “key ring,” the KeePass .zip file can be verified with the .asc file by running the gpg --verify command. See the example below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.jeremyburman.com/posts/files/image_636493394244889067.png"&gt;&lt;img title="image" style="display: inline; background-image: none;" border="0" alt="image" src="https://blog.jeremyburman.com/posts/files/image_thumb_636493394248562143.png" width="680" height="109" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The main thing that you are looking for here is the “Good signature” message, and the warning message here can be ignored. You can also compare the key fingerprint to the one that was displayed on the website where you downloaded the .asc file from.&lt;/p&gt;



&lt;h3&gt;Download and Verify Electrum-LTC&lt;/h3&gt;

&lt;p&gt;The good news is that now that you’ve verified KeePass, the process for Electrum-LTC is nearly identical. Head over to the &lt;a href="https://electrum-ltc.org/" target="_blank"&gt;Electrum-LTC site&lt;/a&gt; and first download the .exe (once again, I recommend the portable version) and the corresponding .asc file. Also, visit the link to the “Pooler” signature. I’ve highlighted all three items for the portable version in the image below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.jeremyburman.com/posts/files/image_636493394250213958.png"&gt;&lt;img title="image" style="display: inline; background-image: none;" border="0" alt="image" src="https://blog.jeremyburman.com/posts/files/image_thumb_636493394252869717.png" width="430" height="205" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Import the Pooler public key (example below) and then run the gpg --verify command on the Electrum files.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.jeremyburman.com/posts/files/image_636493394254632508.png"&gt;&lt;img title="image" style="display: inline; background-image: none;" border="0" alt="image" src="https://blog.jeremyburman.com/posts/files/image_thumb_636493394257860387.png" width="682" height="109" /&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;Fwew! That was a bit of work, but now with both the programs verified we are finally ready to setup our Litecoin wallet. However, I am going to end this post here and will save that for the next one.&lt;/p&gt;



&lt;p&gt;Reference Links&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Windows 10 – &lt;a href="https://docs.microsoft.com/en-us/windows/wsl/install-win10" target="_blank"&gt;Install Windows Subsystem for Linux&lt;/a&gt;&lt;/li&gt;

  &lt;li&gt;&lt;a href="https://www.gpg4win.org" target="_blank"&gt;Gpg4win&lt;/a&gt; (alternative to using gpg within WSL)&lt;/li&gt;

  &lt;li&gt;KeePass – &lt;a href="https://keepass.info/download.html" target="_blank"&gt;Releases&lt;/a&gt;&lt;/li&gt;

  &lt;li&gt;KeePass – &lt;a href="https://keepass.info/integrity_sig.html" target="_blank"&gt;Signatures&lt;/a&gt;&lt;/li&gt;

  &lt;li&gt;&lt;a href="https://electrum-ltc.org/" target="_blank"&gt;Electrum-LTC&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content>
  </entry>
  <entry>
    <id>https://jbminiblog.azurewebsites.net/blog/get-started-with-a-cryptocurrency-on-windows-–-part-1/</id>
    <title>Get Started with a Cryptocurrency on Windows – Part 1</title>
    <updated>2017-12-20T02:49:25Z</updated>
    <published>2017-12-16T02:39:06Z</published>
    <link href="https://jbminiblog.azurewebsites.net/blog/get-started-with-a-cryptocurrency-on-windows-–-part-1/" />
    <author>
      <name>test@example.com</name>
      <email>Jeremy Burman</email>
    </author>
    <category term="cryptocurrency" />
    <content type="html">&lt;p&gt;While I am not going to claim any expertise in cryptocurrency, I have spent a bit of time dabbling in it in order to gain a working knowledge as well as keep a bit on hand as an alternative investment. There are many options out there for acquiring cryptocurrencies and storing or spending them on a variety of computer platforms. I am going to document one option that I use on Windows and the steps and tools needed to make it work. I will focus specifically on Litecoin here, but working with Bitcoin would be nearly identical. This Part 1 post will be fairly brief – I’ll describe the list of tools and steps that I use and then in a subsequent post (or posts) I will go into a little more detail on how to complete the steps.&amp;#160; Some of the steps here are optional and really depend on how careful you want to be. I’ll label the optional steps, but I think they are good habits to follow anyway.&lt;/p&gt;    &lt;p&gt;First off, why go through all this trouble in the first place when one could simply buy some coins on Coinbase or another online wallet and leave them there? Also, why Windows?? Well, to answer the first question, ideally you should keep as much control over your money as you can. Once your local wallet is setup, it’s trivial to transfer your coins to it. There’s always the risk that an online site could be infiltrated by hackers and your money taken out. Obviously, there’s also risks to storing it yourself, but you are also a much smaller target to go after and you have more control (and at the end of the day, that’s what cryptocurrency is all about, having control over your money.) As for the use of Windows, the simple answer is that I am a long-time Windows user who enjoys the OS. I spend a lot of time on my Surface Pro so that is the environment in which I am most comfortable getting setup to work with cryptocurrency. There are a lot of mobile apps and wallets out there that are fairly turnkey, but setting up a wallet on a PC is a bit more involved. I am not sure how much documentation is out there on how to get started on Windows so I thought that it might be helpful to record a few notes on my blog.&lt;/p&gt;    &lt;p&gt;Here are the list of tools that I use:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Windows 10 Pro (Windows 10 Home can be used for most of this, but I recommend the Pro version mainly for the next point which is…)&lt;/li&gt;    &lt;li&gt;BitLocker – this is optional, but BitLocker allows drives to be encrypted. This includes SD cards, so that, for example, I can encrypt a MicroSD card plugged into my Surface and then remove it to store offline.&lt;/li&gt;    &lt;li&gt;Windows Subsystem for Linux (WSL) – I use the GPG (GNU Privacy Guard) tools to verify file downloads – again, an optional step but recommended. There are also other ways to do this, but this is the methodology that I went with.&lt;/li&gt;    &lt;li&gt;KeePass – a password manager – I use this to store the local wallet password and my wallet seed.&lt;/li&gt;    &lt;li&gt;Electrum-LTC – Litecoin wallet (there’s also an Electrum version for Bitcoin)&lt;/li&gt;    &lt;li&gt;Coinbase.com – very easy to use site for buying Bitcoin, Litecoin, or Ethereum&lt;/li&gt; &lt;/ul&gt;    &lt;p&gt;The basic steps to getting setup will be:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Download and verify KeePass and Electrum-LTC&lt;/li&gt;    &lt;li&gt;Setup both of the above tools&lt;/li&gt;    &lt;li&gt;Receive and send some Litecoin&lt;/li&gt; &lt;/ul&gt;    &lt;p&gt;That’s it for this post. If any of this sounds interesting to you, then stick around for another write-up where I’ll have details about each of the steps above.&lt;/p&gt;</content>
  </entry>
  <entry>
    <id>https://jbminiblog.azurewebsites.net/blog/quick-look-liquid-templating-aspnet/</id>
    <title>A Quick Look at Liquid Templating in ASP.NET</title>
    <updated>2017-12-02T12:37:07Z</updated>
    <published>2017-12-02T12:36:00Z</published>
    <link href="https://jbminiblog.azurewebsites.net/blog/quick-look-liquid-templating-aspnet/" />
    <author>
      <name>test@example.com</name>
      <email>Jeremy Burman</email>
    </author>
    <category term="quicklook" />
    <category term="asp.net core" />
    <content type="html">  &lt;p&gt;A few weeks ago I watched &lt;a href="https://www.youtube.com/watch?v=HeDjv3blBjQ&amp;amp;list=PL1rZQsJPBU2StolNg0aqvQswETPcYnNKL&amp;amp;index=1" target="_blank"&gt;an episode of the ASP.NET Community Standup&lt;/a&gt; that was recorded with Sebastien Ros where they covered updates around the &lt;a href="https://orchardcore.readthedocs.io" target="_blank"&gt;Orchard Core&lt;/a&gt; CMS product. While Orchard Core appears to be coming along nicely, one of the demos in particular caught my eye, in that it has support for Liquid templates built in. Years ago, I had utilized Liquid when doing some work with Shopify and I remembered coming away fairly impressed at how easy it was to use (here’s an &lt;a href="https://www.shopify.com/partners/blog/115244038-an-overview-of-liquid-shopifys-templating-language" target="_blank"&gt;intro to Liquid&lt;/a&gt; on the Shopify blog.) The demo piqued my interest to see how Orchard Core supported Liquid, and to see how hard it might be to add similar support into something that I might build myself. Fortunately, Orchard Core is all open source, so it was easy enough to track down that it is using a package named &lt;a href="https://github.com/sebastienros/fluid" target="_blank"&gt;Fluid.Core&lt;/a&gt; that is maintained by Sebastien Ros.&lt;/p&gt;    &lt;p&gt;The steps getting going are pretty straight forward. (I will show a few samples below from a little proof of concept app that I built called &lt;a href="https://github.com/jburman/blog-content/tree/master/FluidTagHelper/FluidTagHelper" target="_blank"&gt;FluidTagHelper&lt;/a&gt;, so check that out if you want to just browse some code instead.)&lt;/p&gt;    &lt;p&gt;First, obviously you need to add the Fluid package. Currently, Fluid.Core is in prerelease so…&lt;/p&gt;    &lt;pre&gt;&lt;code&gt;dotnet add package Fluid.Core --version 1.0.0-beta-9399&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;Then, before you can render a template, you need to white list the Types that will be used in the template. Think of these as similar to your View Model types. The easiest way is to register an entire class at startup (but you can also define specific members). For example, in my TagHelper demo I registered a Fruit type during &lt;a href="https://github.com/jburman/blog-content/blob/master/FluidTagHelper/FluidTagHelper/Startup.cs" target="_blank"&gt;Startup&lt;/a&gt;.&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;TemplateContext.GlobalMemberAccessStrategy.Register&amp;lt;Fruit&amp;gt;();&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;Now, in a view you can take a template string and some data, and call FluidTemplate.TryParse and then construct a TemplateContext to render the data with. In my demo app, this is split between the &lt;a href="https://github.com/jburman/blog-content/blob/master/FluidTagHelper/FluidTagHelper/Pages/Index.cshtml.cs" target="_blank"&gt;Index.cshtml.cs&lt;/a&gt; and the &lt;a href="https://github.com/jburman/blog-content/blob/master/FluidTagHelper/FluidTagHelper/TagHelpers/FluidTagHelper.cs" target="_blank"&gt;FluidTagHelper.cs&lt;/a&gt;.&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;string fluidTemplate = @&amp;quot;&amp;lt;ul class=&amp;quot;&amp;quot;list-group&amp;quot;&amp;quot;&amp;gt;
{% for fruit in model %}
&amp;lt;li class=&amp;quot;&amp;quot;list-group-item&amp;quot;&amp;quot;&amp;gt;{{fruit.Name}} - {{fruit.Weight}} lbs&amp;lt;/li&amp;gt;
{% endfor %}
&amp;lt;/ul&amp;gt;&amp;quot;;

Fruit[] fluidModel = new[]
{
    new Fruit()
    {
        Name = &amp;quot;Banana&amp;quot;,
        Color = &amp;quot;Yellow&amp;quot;,
        Weight = 0.75m
    },
    new Fruit()
    {
        Name = &amp;quot;Orange&amp;quot;,
        Color = &amp;quot;Orange&amp;quot;,
        Weight = 1.0m
    }
};

if (FluidTemplate.TryParse(fluidTemplate, out var template))
{
    var templateContext = new TemplateContext();
    templateContext.SetValue(&amp;quot;model&amp;quot;, fluidModel);
    string renderedTemplate = template.Render(templateContext);
}&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;And that’s it in a nutshell! I think that Liquid templating could be useful in any scenario where you may want a (fairly technical) end user to be able to customize application views, or even for an application developer who may want to customize various displays without having to redeploy new code. Fluid.Core looks to be a nice option that is coming along in the ASP.NET Core space.&lt;/p&gt;</content>
  </entry>
  <entry>
    <id>https://jbminiblog.azurewebsites.net/blog/csharp-multiple-return-values/</id>
    <title>A Quick Look at Multiple Return Values</title>
    <updated>2017-11-08T02:35:40Z</updated>
    <published>2017-11-08T02:30:52Z</published>
    <link href="https://jbminiblog.azurewebsites.net/blog/csharp-multiple-return-values/" />
    <author>
      <name>test@example.com</name>
      <email>Jeremy Burman</email>
    </author>
    <category term="C#" />
    <content type="html">&lt;p&gt;One of my favorite features that was added in C# 7 was support for multiple variable assignment from return values via the use of &lt;strong&gt;&lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/tuples" target="_blank"&gt;Tuples&lt;/a&gt;&lt;/strong&gt;. Here’s a quick example of a function that declares multiple return values.&lt;/p&gt;  &lt;pre&gt;&lt;code&gt;public (Article[] articles, string[] tags) FindArticles(DateTimeOffset begin, DateTimeOffset end)
{
    // query data ...
    return (articles, tags);
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And calling it would then look like…&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(var articles, var tags) = FindArticles(begin, end);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The alternatives to this prior to C# 7 would be either to declare a class to wrap the values into a single return type, to create out parameters, or else to make multiple function calls (e.g. FindArticles/FindTags…).&lt;/p&gt;

&lt;p&gt;The new C# 7 syntax provides a nice clean symmetry between the return type declaration and the assignment statement. Under the hood, the C# compiler is using &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.valuetuple?view=netstandard-2.0" target="_blank"&gt;System.ValueTuple&lt;/a&gt;&lt;strong&gt;&lt;/strong&gt; to represent the return values. If you’re targeting a .NET Framework version earlier that 4.7 or targeting NET Standard 1.x, then you’ll need to add a reference to the &lt;a href="https://www.nuget.org/packages/System.ValueTuple/" target="_blank"&gt;ValueTuple NuGet package&lt;/a&gt;.&lt;/p&gt;



&lt;p&gt;As with most new language features, there are a few caveats to consider.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;First, the multiple return values feature should not replace proper modelling or DTOs. Think of it more as a garnish to mix into your existing code to make certain calls (or combination of calls) more convenient. For example, it can eliminate some of the “throw away” types that are created simply for returning groups of objects together.&lt;/li&gt;

  &lt;li&gt;Currently, it is recommended that multiple return value use is kept internal to a library or application and that is not be used as part of its public interface. Consider a scenario where you would have to work with a library from an earlier version of C#, and having to deal with the ValueTuple directly is not so useful.&lt;/li&gt;

  &lt;li&gt;There is extra work needed to make C# 7 work with ASP.NET projects hosted on the .NET Framework (especially if you are upgrading an older existing project). You will need to make sure the ASP.NET CodeDom compiler NuGet package for ASP.NET is installed (a.k.a. &lt;a href="https://www.nuget.org/packages/Microsoft.CodeDom.Providers.DotNetCompilerPlatform/" target="_blank"&gt;Microsoft.CodeDom.Providers.DotNetCompilerPlatform&lt;/a&gt;), which will in turn bring in the Roslyn compiler NuGet package (&lt;a href="https://www.nuget.org/packages/Microsoft.Net.Compilers/" target="_blank"&gt;Microsoft.Net.Compilers&lt;/a&gt;). &lt;strong&gt;&lt;font style="background-color: rgb(255, 255, 0);"&gt;Be careful here!&lt;/font&gt;&lt;/strong&gt; If your target environment uses the 4.5.x runtime, then the highest compatible version of Microsoft.Net.Compilers is 1.3.2, which effectively limits you to C# 6. NuGet may automatically bring in the latest 2.x Roslyn compiler package, which will lead to compilation errors once you deploy your app to the 4.5.x running server (been there, got the T-shirt.)&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;&lt;/h1&gt;



&lt;h2&gt;Deconstructing to Multiple Variable Assignment&lt;/h2&gt;

&lt;p&gt;The formal term for the assignment of multiple discrete variables from a return value is called &lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/deconstruct" target="_blank"&gt;Deconstruction&lt;/a&gt;&lt;strong&gt;.&lt;/strong&gt; While the syntax shown above utilizes tuples, C# 7 allows other types to be used for multiple assignment as well.&amp;#160; Deconstruction provides a compact syntax for assigning variables from values contained in an object. It also somewhat bridges the gap between allowing the new C# syntax to be used with a function while keeping that function backwards compatible with C# 6 and earlier consumers (see the final example in this post). Support for deconstructing an existing type can be added via a convention method named &lt;strong&gt;Deconstruct&lt;/strong&gt; and giving the method one or more &lt;strong&gt;out&lt;/strong&gt; &lt;strong&gt;parameters&lt;/strong&gt;.&lt;/p&gt;



&lt;p&gt;As an example, let’s wrap up the return values from the first example into a new type.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public class FindArticlesResult
{
    public Article[] Articles;
    public string[] Tags;

    public void Deconstruct(out Article[] articles, out string[] tags)
    {
        articles = Articles;
        tags = Tags;
    }
}&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;The FindArticles method is then updated as follows…&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public FindArticlesResult FindArticles(DateTimeOffset begin, DateTimeOffset end)
{
    // query data ...
    return new FindArticlesResult()
    {
        Articles = articles,
        Tags = tags
    };
}&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;From C# 7 it can be called with the same syntax as before.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(var articles, var tags) = FindArticles(begin, end);

// NOTE: multiple assignment can be done from an existing variable as well.
var result = FindArticles(begin, end);
(var articles, var tags) = result;&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;From C# 6 and earlier, the result can be accessed directly.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var result = FindArticles(begin, end);
var articles = result.Articles;
var tags = result.Tags;&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;That’s all for now! Be sure to check out the great documentation on &lt;a href="https://docs.microsoft.com" target="_blank"&gt;docs.microsoft.com&lt;/a&gt; that covers &lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/tuples" target="_blank"&gt;Tuples&lt;/a&gt; and &lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/deconstruct" target="_blank"&gt;Deconstruction&lt;/a&gt; in more detail.&lt;/p&gt;</content>
  </entry>
  <entry>
    <id>https://jbminiblog.azurewebsites.net/blog/first-post/</id>
    <title>New blog!</title>
    <updated>2017-11-03T19:21:32Z</updated>
    <published>2017-11-03T18:57:00Z</published>
    <link href="https://jbminiblog.azurewebsites.net/blog/first-post/" />
    <author>
      <name>test@example.com</name>
      <email>Jeremy Burman</email>
    </author>
    <content type="html">&lt;p&gt;Welcome to my new blog!&lt;/p&gt;  &lt;p&gt;For quite a while now, I’ve bought into the opinions voiced by blogging celebrities such as &lt;a href="https://www.hanselman.com/blog/" target="_blank"&gt;Scott Hanselman&lt;/a&gt; and &lt;a href="https://www.troyhunt.com/" target="_blank"&gt;Troy Hunt&lt;/a&gt;. For example, &lt;a href="https://www.hanselman.com/blog/YourWordsAreWasted.aspx" target="_blank"&gt;Scott makes compelling arguments that&lt;/a&gt; more bloggers are needed to strengthen their respective communities, and also that you should also “own your words.” That is, don’t do all your writing in a walled garden owned by a &lt;a href="https://www.facebook.com/" target="_blank"&gt;giant social media company&lt;/a&gt;. That resonates with me. I also like the idea of using a blog as a tool for personal documentation and as a public log for sharing research with others, which is how I’ve heard Jon Skeet, another one of my favorite bloggers, describe &lt;a href="https://codeblog.jonskeet.uk/" target="_blank"&gt;his blog&lt;/a&gt;. Finally, I want to use my blog as a tool to simply help me focus on researching and documenting topics that interest me. However, there’s a big gap between wanting something intellectually and sitting down to put in the time to build it.&lt;/p&gt;  &lt;p&gt;So, this is my first post - short and sweet. In the next post, I plan to dive straight into some technical content!&lt;/p&gt;</content>
  </entry></feed>