Two weeks in

Sunday, 29 March 2020

I’ve been working from home for two weeks now. The first week I’d already planned in advance once the MVP Summit went virtual (so I’d be attending sessions online in the morning and then working the rest of the day). But by that first Wednesday the rest of my office had followed the same pattern. It was a bit sad, as I had a colleague leaving. Usually as an office we’d make a point of going out to lunch and enjoying our last day together, but social distancing had other plans.

I originally set up camp in our ‘middle’ room - which is pretty much where everyone moves through. While it is nice to be in the centre of all the action, it did mean others had to tip-toe around when I was on a conference call. So last weekend I decided maybe I’d be better moving down to our ‘end’ room. The TV and piano are there, but for daytime hours, I can sit down here uninterrupted.

My home desk

It’s quite a pleasant spot. I can look off to the side and see out to our garden and beyond. Last year I had been researching standing desks. I think if I end up working here long term, I might follow that up again.

Last weekend I brought home my 3 monitors + stands from the office. Sadly one of the monitors refused to start up when I got it home. The previous week I’d bought a new Acer 23” monitor, so for now I’ve got that in the middle, with the two remaining AOCs either side. It would have been fun to have 4 monitors. Maybe later.

Remote office not required I saw a tweet by Jason Fried offering to refund the purchase price of his book (co-authored with David Heinemeier Hanson), “Remote: Office Not Required”. I was inspired to purchase a hard copy of it, and while I was there I figured I’d grab “It doesn’t have to be crazy at work”.

I’ve had previous jobs where I worked from home for a day a week. This is the first time I’ve done it for any consecutive period.

The “Remote” book is quite an easy read. Each chapter is divided up into a number of 1-3 page bites. It’s certainly got me thinking about whether this is something I’d want to continue doing even after the current situation.

A point the authors make is it doesn’t have to be “all or nothing”. Working from home Monday to Thursday and heading in to the office on Friday could be an option. Why Friday? Well traditionally that’s our ‘team pizza lunch’ day :-)

The fact that my entire company is working from home potentially makes this more viable, as whether they like it or not, everyone is hopefully now learning now to be effective working from home. I’d like to think that learning will remain long after the pandemic has gone.

COVID-19

Wednesday, 18 March 2020

Wow, that escalated fast. In the space of just a few weeks:

To avoid being cooped up in the house the entire day, the last couple of mornings before starting work I’ve gone for a short walk around the neighbourhood with my other daughter. It emulates my walk to the bus stop. Hopefully we can make it a regular thing.

Two pairs of legs, with concrete path and grass with leaves

Apparently my legs are a bit longer than hers, so a short break on a seat in the park along the way is required :-)

This is going to be a very disruptive time. Things aren’t too bad (yet) where I live, but the stories from overseas are quite scary. Take care of yourselves and your loved ones.

March update

Friday, 6 March 2020

January and February have come and gone, and March is now well underway. Autumn seems to have definitely hit Adelaide, though I wonder if there might still be some warmer weather around before Winter arrives? Time will tell.

Out of the ordinary

Also interesting to read about Microsoft asking their Redmond-based employees to work from home (if possible) for the rest of March.

ADNUG

The Adelaide .NET User Group is back for 2020. There’s been huge interest in next week’s meeting, which is great to see. I’m hoping to fill out the speaker schedule for the next few months. Do get in touch if you’d like to present to the group (and that can be in-person, or remote via Skype/Teams).

If I have one wish for the group, it’s that I could find someone(s) to share the organising with. It would be good to have some load balancing (or at least a fail-over cluster!) Related to that, we’ve actually launched the ADNUG 2020 Member Survey. Please share your thoughts (and be in the running for a $100 book voucher).

I must say it’s been really great to have Simon and Kristine from Encode Management on-board as both sponsors and supporters - and I know they’re also working with other meetups in Adelaide too. It would be easy (and I think it has happened in the past) that sponsors just give some money, or might just pop their head in, but the folks from Encode are regular attendees and are often one of the last to leave after helping pack up. That sincerity and encouragement count for a lot in my book. And speaking of books, it’s Encode that are putting up the aforementioned book voucher. Awesome!

DDD Adelaide 2020

I caught up with Andrew this week to kick of planning for DDD Adelaide 2020, with our traditional ‘DDDumplings’ lunch meeting. We should really get Dumpling King on board as a major sponsor :-)

Welcome to 2020

Thursday, 9 January 2020

Christmas has come and gone, and now it’s 2020. If there’s one thing that’s been a constant over this Summer period, it’s that it feels like we’re under seige from bushfires.

Here’s a view not that far from where I live. That’s a smoke haze (not really thick, but noticeable ), from fires on Kangaroo Island around 200km south. There’s been other fires around South Australia in the Adelaide Hills and over on York Peninsula. And then interstate there’s fires all over the place - basically all around Australia. A good drop of rain would not go astray.

Dry paddocks with smoke haze

I’ve been enjoying some time off - catching up with family, the odd bike ride or two, a few jobs around the house and just trying to switch off for a bit.

More to come…

.NET RuntimeIdentifier vs RuntimeIdentifiers

Thursday, 5 December 2019

A Runtime Identifier (RID) is used to identify target platforms where a .NET Core application runs. They come into play when packages contain platform-specific assets (eg. native code for Linux, or Windows 64bit).

You can specify a single RID using the <RuntimeIdentifier> element in the project file, or to specify multiple RIDs use <RuntimeIdentifiers>.

Many dotnet command also can specify --runtime (or -r).

According to the documentation, if you only need to specify a single runtime then using <RuntimeIdentifier> will also result in faster builds.

I’ve noticed some other subtle difference between the singular and plural forms of this element.

Let’s create a simple .NET Core console app:

md rid
cd rid
dotnet new console

By default, the csproj (named rid.csproj in this case) looks like this:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

</Project>

If you look inside the obj directory, you’ll find a file named rid.csproj.nuget.dgspec.json. Its contents look like this:

{
  "format": 1,
  "restore": {
    "C:\\tmp\\rid\\rid.csproj": {}
  },
  "projects": {
    "C:\\tmp\\rid\\rid.csproj": {
      "version": "1.0.0",
      "restore": {
        "projectUniqueName": "C:\\tmp\\rid\\rid.csproj",
        "projectName": "rid",
        "projectPath": "C:\\tmp\\rid\\rid.csproj",
        "packagesPath": "C:\\Users\\david\\.nuget\\packages\\",
        "outputPath": "C:\\tmp\\rid\\obj\\",
        "projectStyle": "PackageReference",
        "fallbackFolders": [
          "C:\\Program Files\\dotnet\\sdk\\NuGetFallbackFolder"
        ],
        "configFilePaths": [
          "C:\\Users\\david\\AppData\\Roaming\\NuGet\\NuGet.Config",
          "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
        ],
        "originalTargetFrameworks": [
          "netcoreapp3.1"
        ],
        "sources": {
          "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
          "https://api.nuget.org/v3/index.json": {}
        },
        "frameworks": {
          "netcoreapp3.1": {
            "projectReferences": {}
          }
        },
        "warningProperties": {
          "warnAsError": [
            "NU1605"
          ]
        }
      },
      "frameworks": {
        "netcoreapp3.1": {
          "imports": [
            "net461",
            "net462",
            "net47",
            "net471",
            "net472",
            "net48"
          ],
          "assetTargetFallback": true,
          "warn": true,
          "frameworkReferences": {
            "Microsoft.NETCore.App": {
              "privateAssets": "all"
            }
          },
          "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\3.1.100\\RuntimeIdentifierGraph.json"
        }
      }
    }
  }
}

If you supply a runtime identifier when running restore, like dotnet restore -r win10-x64, then two extra sections are added to this file. Firstly, under the "netcoreapp3.1" node:

          "downloadDependencies": [
            {
              "name": "Microsoft.AspNetCore.App.Runtime.win-x64",
              "version": "[3.1.0, 3.1.0]"
            },
            {
              "name": "Microsoft.NETCore.App.Runtime.win-x64",
              "version": "[3.1.0, 3.1.0]"
            },
            {
              "name": "Microsoft.WindowsDesktop.App.Runtime.win-x64",
              "version": "[3.1.0, 3.1.0]"
            }
          ]

and secondly under the second "C:\\tmp\\rid\\rid.csproj" node, a runtimes section is added:

      "runtimes": {
        "win10-x64": {
          "#import": []
        }
      }

If you instead passed in -r linux-x64 then predictably, those entries refer to linux-x64 instead of win-x64.

Adding <RuntimeIdentifier>win10-x64</RuntimeIdentifier> to the csproj and running dotnet restore has exactly the same effect as if you specified the RID on the command line.

And now running dotnet build with the RID specified results in the compiled application being created in bin\Debug\netcoreapp3.1\win10-x64. Plus, since .NET Core 3 it also defaults to creating a self-contained application (so you get an .exe as well as all the dependent assemblies to allow you to run the application on a machine that didn’t already have the runtime installed)

It’s a slightly different story if you use <RuntimeIdentifiers> though..

You can’t specify multiple RIDs on the command line (well actually in .NET Core 2.2 you could for restore, but not in 3). So let’s change our csproj to have <RuntimeIdentifiers>win10-x64;linux-x64</RuntimeIdentifiers>. and run

dotnet restore

the dgspec.json now contains entries for both platforms. eg.

          "downloadDependencies": [
            {
              "name": "Microsoft.AspNetCore.App.Runtime.linux-x64",
              "version": "[3.1.0, 3.1.0]"
            },
            {
              "name": "Microsoft.AspNetCore.App.Runtime.win-x64",
              "version": "[3.1.0, 3.1.0]"
            },
            {
              "name": "Microsoft.NETCore.App.Host.linux-x64",
              "version": "[3.1.0, 3.1.0]"
            },
            {
              "name": "Microsoft.NETCore.App.Runtime.linux-x64",
              "version": "[3.1.0, 3.1.0]"
            },
            {
              "name": "Microsoft.NETCore.App.Runtime.win-x64",
              "version": "[3.1.0, 3.1.0]"
            },
            {
              "name": "Microsoft.WindowsDesktop.App.Runtime.win-x64",
              "version": "[3.1.0, 3.1.0]"
            }
          ],

and

      "runtimes": {
        "linux-x64": {
          "#import": []
        },
        "win10-x64": {
          "#import": []
        }
      }

but now if you run dotnet build, something interesting… there’s no bin\Debug\netcoreapp3.1\win10-x64 or bin\Debug\netcoreapp3.1\linux-x64 directories like you might be expecting. Instead there’s just the regular compiled assembly in bin\Debug\netcoreapp3.1! Almost as if you’d never set a RID at all.

What you can do now though, is build for both platforms consecutively. eg.

dotnet build -r win10-x64
dotnet build -r linux-x64

and you get both self-contained builds for win10-x64 and linux-x64 platforms! Plus, as you’ve already done a restore, you can make the build faster by passing in --no-restore so it doesn’t bother trying to restore again.

So if you’re targetting a single platform, use -r on the command-line or <RuntimeIdentifier>. If you’re targetting multiple platforms, use <RuntimeIdentifiers> and then use separate restore and build steps