Posts

Never use float for money

The web is riddled with articles on this very topic, yet it bares repeating: never use float for money. I repeat: never never never never never use a floating point data type to represent monetary values or do financial math. Why? Single and Double precision floating point numbers are not accurate. Ironically, it's by design. They are optimized for performance where absolute accuracy is not a concern. Microsoft talks about it briefly here:  https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/floating-point-numeric-types [...]there's no double or float instance that exactly represents 0.1. Because of this difference in numeric types, unexpected rounding errors can occur in arithmetic calculations when you use double or float for decimal data. Baeldung has an excellent writeup on the science behind why floats behave the way they do:  https://www.baeldung.com/cs/floating-point-numbers-inaccuracy So what should we use for money and financial calculation...

AES256 Encryption in C#

Every few years, I find myself having to write an AES256 encryption routine for a project. I always end up having to lookup the specifics, so I thought I would write it down this time. What is AES256 AES--Advanced Encryption Standard--is a symmetrical block cipher standard. Symmetrical meaning it uses the same key to both encrypt and decrypt, as opposed to Asymmetrical (eg. TLS) which uses a public/private key pair--a different key to encrypt than to decrypt. Block cipher meaning the encryption is performed by chunking the plain text into blocks and encrypting each block separately. In the case of AES, each block is 128 bits in length. Chunks smaller than 128 bits are padded to create a 128 bit block. At the time of this writing, bank-grade and government standard uses a 256 bit key (AES256) and a CBC--Cipher Block Chaining--mode. With CBC, each plain text block is XOR with the previous encrypted block before being encrypted itself. This requires an initialization vector--a unique, ran...

Pragmatic Architecture. Pragmatic Microservices.

Image
Customer-First. Team-Focused. I like to take a customer-first approach to architecture and software design. A system architecture should always deliver value to the customer. Either directly--features, user experience--or indirectly by enabling teams to deliver value. If a team is going to be able to deliver value, the system needs to be easy to reason over, easy to maintain, easy and safe to extend, and easy to operate. Every architecture or design decision should answer: How does this deliver value to my customer? How does this deliver value to my team? Competing Styles. The Swinging Pendulum. It seems the big debate lately is monolith vs microservices. Academically, each at the opposite end of the spectrum: the massive, single deployable unit monolith on one end and the highly decomposed highly distributed microservices on the other. Each come with their pros and cons and serve teams better depending on team size, skill level, and goals. Notice I didn't include the customer in t...

A .Net Development Rig in Linux

Image
After playing with Rider for a while, I decided to play around with Linux again to see what .Net development is like on Linux rig in 2020. So I fired up an Ubuntu 20.04 LTS VM and started installing. .Net Core After updating the OS with all the latest patches, I installed both .Net Core 2.1 LTS and 3.1 LTS following Microsoft's instructions . wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb sudo dpkg -i packages-microsoft-prod.deb sudo apt-get update; \ sudo apt-get install -y apt-transport-https && \ sudo apt-get update && \ sudo apt-get install -y dotnet-sdk-3.1 dotnet-sdk-2.1 JetBrains IDEs I have a JetBrains Ultimate subscription, so my next setup was installing JetBrains Toolbox. There is zero documentation on doing so, but it's pretty simple. Just download the tar ball from JetBrains, extract it to a directory of your choosing, and run it. Using the ToolBox, I installed my IDEs--Rider, In...

My Experience with JetBrains Rider

Disclaimer: This is an OpEd and mostly anecdotal. Performance wasn't measured, just perceived based on whether it left like the IDE was hanging a lot or productivity was impacted. I'll start off by saying: there is no replacement for Visual Studio. None. That's my opinion anyway. That said, JetBrains Rider is a decent .Net IDE, especially if you are a ReShaper fan (I am not) or IntelliJ fan (I am). What made me decide to give it a go? Well, I started work at Linedata as a Cloud Solution Architect and Application Architect. They are heavy users of ReSharper, and use it to enforce code formatting, quality, standards, and test coverage ( dotCover ) as part of their CI builds. It only took a few hours of me getting fed up with ReSharper crippling Visual Studio for me to install Rider and give it a go. I've been using it at work since. Some take-aways After using Rider as my primary C# IDE for a few months, here's my impression... Good Impressions P...

Static Readonly instead of Const in C#

I have always considered it a best practice to use  static readonly  instead of  const  in C#. Here’s why… The  const  keyword tells the compiler to replace the constant token in your code with the literal value you have defined for the constant. You can see this if you look at the IL: The C# code… const string HELLO = "Hello" ; ... Console . WriteLine ( HELLO ); Console . WriteLine ( HELLO ); Compiles to the IL… .field private static literal string HELLO = "Hello" ... IL_0001: ldstr "Hello" IL_0006: call void [System.Console]System.Console::WriteLine(string) IL_000b: nop IL_000c: ldstr "Hello" IL_0011: call void [System.Console]System.Console::WriteLine(string) Notice that the literal  "Hello"  is loaded twice. Using  static readonly  provides us similar semantics–a global value that cannot be changed–but rather than references being replaced with literals by the compiler, it remains ...

Code Coverage for Multiple Projects in a Single Build using Dotnet Test and Coverlet

Most of the time, your solution will have more than one project and a test unit project for each of those. Azure DevOps only, as of this writing, only allows you to update a single code coverage summary. If you upload more than one, each overwrites the next and only the last one remains. To accomplish this, we can use the merge functionality in Coverlet . I use the MSBuild extension, because it is better suited for CI pipelines. In your test project XML, add the package... <PackageReference Include="coverlet.msbuild" Version="2.7.0">     <PrivateAssets>all</PrivateAssets>     <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference> Then, in your dotnet test command or msbuild command, tell it to use Coverlet and to merge results. If you're using Azure DevOps, your test task looks this... (line wrapped for read ability in the article) - task: DotNetCoreCLI@2 displayName: Test i...