Find where an object is unintentionally being converted to a string

Monday, 11 February 2019

I’ve been applying the Replace Primitive with Object pattern to a code base - changing what used to be strings into a custom type (which not only makes the code more readable, but now ensures through type safety that you can’t accidentally pass in any old random values to methods that used to just take strings.

The code has tests, and after applying the refactoring, I have a failing test - which hints that somewhere there’s an implicit conversion from the new strongly typed object back to a string. The test’s failing assertion says it received “MyNamespace.TypedThing” (which is what the default implementation of ToString() returns), rather than the wrapped string value that TypedThing encapsulates.

My initial suspicion is that there’s probably code similar to this that’s causing the problem:

TypedThing thing = new TypedThing("thingy");
string s = $"{thing}";

ReSharper has a cool utility - “Structural Search and Replace”. Unfortunately it doesn’t work for single expressions like "{thing}".

If I was cluey, I might be able to write a Roslyn tool to search the code and find instances like that, but that’s going to take a bit more effort than I want.

What about this: temporarily override the ToString() method on my custom type, and make it throw an exception!

It’s a bit of a sledgehammer, but it worked!

As it turns out my suspicion was not quite correct. The offending code was actually assigning the custom type to an Object type (which explains the lack of compiler type warnings), which later on must be converted to a string.

Now that I could see an example, I could use ReSharper’s SSR to confirm that was the only instance of that kind of assignment (SSR can be used as I’m searching for an assignment statement, not just a single expression). Just for good measure, I’ll also re-run the entire test suite to make sure there aren’t any other similar problems still hiding.

Choco list -localonly (Feb 2019 Edition)

Sunday, 3 February 2019

What software / applications am I using on my laptop (February 2019 Edition) according to Chocolatey? Here’s an edited list of the output from choco list -localonly:

Package Version   Comments
7zip 18.6    
audacity 2.3.0 Audio editor  
becyicongrabber Icon extractor (for creating Chocolatey packages)  
beyondcompare My favourite file comparison tool  
beyondcompare-integration 1.0.1 Configure Beyond Compare for TortoiseGit/Svn  
dellcommandupdate-uwp 3.0.0 Dell’s driver update app  
dns-benchmark 1.3.6668.0 Useful DNS checker  
dotnetdeveloperbundle RedGate’s .NET tools  
dropbox 41.4.80    
fiddler 5.0.20182.28034    
FiraCode 1.206 Nice developer font  
Firefox 57.0.4    
git 2.20.1    
GoogleChrome 63.0.3239.132    
keepass 2.41 Password manager  
mousewithoutborders Share mouse across laptop and desktop PCs  
msbuild-structured-log-viewer 2.0.61    
nodejs 11.9.0    
notepadplusplus 7.6.3 Using this less now compared to VS Code  
nuget.commandline 4.9.2    
obs-studio 22.0.2 Video / screen recording  
OctopusTools 5.2.0    
Office365ProPlus 2016.20170321 4.1.5    
PDFXchangeEditor 7.0.328.2 My favourite  
Pester 4.4.1 PowerShell unit tests  
pingplotter 5.8.10 Useful visual ping network status  
powershell-core 6.1.2    
procmon 3.50 SysInternals Process Monitor  
resharper-clt.portable 2018.3.2 ReSharper’s free command-line tools  
resharper-ultimate-all 2018.3.2    
screentogif 2.16 Handy screen recorder  
snagit 2019.1.0 Screen grabber  
sql-server-2017 14.0.1000    
sql-server-management-studio 14.0.17289.1    
tailblazer Text/log file viewer  
ubiquiti-unifi-controller 5.9.29 Software for managing UniFi wireless access points  
vagrant 2.2.3 Manage virtual machines  
visualstudio2017enterprise 15.2.26430.20170605    
visualstudiocode 1.19.3    
vsts-cli Command line tool for managing Azure DevOps  
vswhere 2.6.7    
wifiinfoview 2.42    
windirstat Where’s all that disk space being used?  
wireshark 2.6.5    
x-lite VoIP client  
yarn 1.13.0    
zoomit Great for presentations  

This is also a good basis for refreshing my Boxstarter scripts.

TimeoutException (aka Tour Down Under 2019 and a week off)

Sunday, 27 January 2019

Back at work for a couple of weeks of 2019 and I don’t want to rush things too much, so I organised to take an extra week off after this year’s Tour Down Under bike ride.

David, his son and his dad after completing the TDU

Last year’s community ride (the ‘Challenge Tour’) had to be cancelled due to hot weather. We’ve had our share of hot weather again this year, but fortunately Saturday (previously Friday) turned out to be ideal. This year I rode with my dad and my son - 3 generations of Gardiners! Very proud of my son, who completed the 100km distance (his furthest ridden) plus (impressing a lot of our fellow riders) he did it on a mountain bike (as he doesn’t have a road bike).

I didn’t need the week off to recuperate from the ride - instead I was catching up with relatives visiting Adelaide! It was great to see them lots of time during the week.

We all just made it through the 46.6°C record maximum temperature for Adelaide on Thursday (that was a really, really hot day).

A ropes course
I watched as my son and his cousin did the ropes course at West Beach
Vanilla slice
French monopoloy game board
French Monopoly - Relying on my niece to translate

I’m finishing off the mini-break with the Australia Day long weekend. Caught up with the visiting rellies one last time (before they flew home) for morning tea/lunch/kicking the footy in the park (how Aussie is that!) following by dinner with my folks. A really nice day!

Installing .NET Core SDK for Azure Pipelines builds

Sunday, 13 January 2019

How do you ensure that the correct version of .NET Core SDK is installed for your Azure Pipeline builds? You could install it manually on your build agents, but wouldn’t it be better to automate it?

The .NET Core Tool Installer Task can be used for this, and if you don’t change the version of the SDK that you require frequently, very often that’s enough.

When you’re developing .NET Core applications, you can indicate which version of the SDK you require to build with by using a global.json file.

Unfortunately, the Installer Task doesn’t currently know about global.json, so you might feel like you’re doubling up - specifying the required version not only in that file but also in the configuration of the Installer Task. Don’t do that!

With a bit of PowerShell, that can be done.. Create a PowerShell Task that runs before the Installer task and use it to set a variable that can then be used by the following task(s).

If you’re using YAML, the task definitions would look something like this:

- powershell: |
    $PathToGlobalJson = Join-Path -Path $Env:BUILD_SOURCESDIRECTORY -ChildPath "global.json"
    $GlobalJson = Get-Content -Raw -Path  $PathToGlobalJson | ConvertFrom-Json
    $Version= $GlobalJson.sdk.version

    Write-Host ("##vso[task.setvariable variable=SdkVersion;]$Version")
  displayName: 'Parse global.json'

- task: [email protected]
  displayName: 'Use .NET Core sdk $(SdkVersion)'
    version: '$(SdkVersion)'

2018 draws to a close..

Wednesday, 26 December 2018

Stone stairway, with sunlight casting shadows

2018 is almost done. It’s the day after Christmas, about 38°C outside (just over 100°F in the old money - not uncommon for this time of year in Adelaide). As I sit here under the cooling, gentle breeze from the air conditioner, I’ve compiled some of my 2018 highlights. (Let me know in the comments if I’ve missed something obvious)


RL Solutions are/have merged with Datix. No changes yet, other than getting to meet a couple of people from the Datix side (including from their Melbourne office).

Our Adelaide team also grew this year with some new hires. We do miss Tom (having lost him to Toronto), but we’ve managed to survive, and it was great to have him back for a week last month. A part from my coding and team lead responsibilities, Tom’s move has meant I’ve picked up additional roles of office grocery/supplies organiser and local IT support.

One particular recent highlight was upgrading the office to a 1G fibre Internet connection, taking advantage of the 10G Adelaide initiative. That’s been a huge win - bandwidth is essentially no longer a constraint on getting things done.

Tarts and fruit mince pies
Toronto sent a lovely Christmas present to the Adelaide office. Yum!

User Group

The Adelaide .NET User Group has finished on a positive note. We’ve had increased attendances the last few months which is really encouraging. We’ve also had a sponsor come on board, which means we can run meetings for free now that our pizza costs are covered.

People seated, watching a presentation

It would be great to have others join me in organising the group - it does concern me that I’m the ‘single point of failure’ at the moment.

In addition to monthly meetings, I’m looking forward to some announcements in the new year about a bigger developer event for Adelaide.


Managed to do some user group talks locally as well as while I was in Toronto, but the highlight for the year was being picked to present as part of .NET Conf.


A bit less this year - two weeks in North America in March (Toronto for work and then Seattle/Redmond for the Microsoft MVP Summit). Coming down with a nauseous gastro-type bug for the last couple of days and the flight home was not a highlight. Definitely an incentive to remember good hand hygiene!

We also had a family holiday interstate and flew (instead of driving all the way). More costly, but quicker and less stressful.


A significant time of year, and one I really enjoy. I have many happy memories of Christmases as a child, and I hope we’re creating them for our kids now.

Our family traditions include taking part in our Church’s Road to Christmas ‘Bethlehem re-enactment’, joining with friends to sing carols at a local hospital, attending a Christmas Eve church service, and then gathering with family for a meal on Christmas Day.

Bonus tip: My aunty told me that she buys a platter/plate from a 2nd hand shop for the food that she brings. That way she doesn’t need to worry about having to remember to bring it home.


We bought my son a turtle for his birthday the previous year. ‘Nibbles’ is now fast outgrowing his tank, so the current project is to build a pond out in the garden where he can live (the turtle, not my son!)

The pond shell/liner, redgum wood sleepers, a pump and filter, shade-cloth all add up to be a surprising amount. Not to mention the manual labour of digging the hole in the ground!

I think Nibbles will appreciate it when it’s all done.

Person lowering a turtle into a pond
Nibbles the turtle, about to give the pond a test drive/swim


That’s the band I play in. We’ve had a few gigs this year, and might be doing some recording in 2019. I was sad when Jane (our violin/mandolin player) retired as that left me as the sole string player on ‘Cello. I’ve had to pick up some of Jane’s parts in some of our songs. Our last gig for the year was something a bit different (and special) - playing for Liz (who also sings in our band) as part of her service of ordination to become a Deacon.

David at a band soundcheck
Sound check, with Pete and Keith photo-bombing

When you’re young, you sometimes dream about being a rock-star. Well that hasn’t happened! But I do get to play instruments and sing on stage with good friends, and people seem to like our music, so while I’m not giving up my day job, it is a lot of fun.


I try and get out for a ride when I can. Seemed to be less commute riding this year, but got out for a few Saturdays with the Mud, Sweat and Gears mob. Looking forward to the Tour Down Under in January and riding in the Challenge Tour with my Dad and my Son (3 generations of Gardiners) as well as brother-in-law James.

Bicycle sitting next to a fence, overlooking green rolling hills


I tend not to post much about my family here. If you know me personally then I might have shared a bit more about how we’re all going. Needless to say, the kids are growing up fast!

Thanks for reading, see you in 2019 :-)