Posts

Showing posts with the label C#

Yield in C#

Image
The yield keyword is used when the method or accessor is an enumerator. Using yield return returns one element at a time. The thing to remember here is that IEnumerable/IEnumerable<T> is a stream, not a collection. This is where many developers misuse IEnumerable (myself included once upon a time). Consider the following code: This is probably what you are used to seeing, but is actually a misuse of IEnumerable. The code works just fine, but it is not leveraging the benefits of IEnumerable being a stream. Let's refactor to use yield return: What we are doing now is streaming the elements one at a time. Each iteration by the consumer of this method comes back to the point of the yield and executes the next statement, in this case the while. The benefit? We eliminated a loop and an object allocation. Rather than looping through all the records, building up a list, then looping through the list, we just loop through the records once.

Configuration Reload in .Net

The 12 Factor App guidelines suggest separating configuration from code as a best practice. More specifically, it should be deployed separately as well. We shouldn't have to redeploy the entire application in order to make a configuration change. Ideally, we don't want to have to restart our app either.  This eliminates downtime when making configuration changes that don't otherwise require downtime such as timeout values, retry configuration, logging level, and distributed trace sampling rate. For providers that support it, Microsoft.Extensions.Configuration can reload the configuration when it changes. Let's take a look. We'll be using the JSON file provider for these examples with the following configuration: IConfigurationRoot When we change a configuration value, the value in the IConfiguration instance also changes. The key to making it all work is the reloadOnChange parameter. Given a simple console app, we can see the behavior as we modify the appsettin...

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...

C# DateTime, DateTimeOffset and the Cloud

One thing to remember,  System.DateTime  has no knowledge of timezone. It’s only aware that the date and time represents UTC or the local timezone of the machine on which the code is running. In the cloud, by default (and it’s best to keep it that way), the “server’s” timezone is set to UTC. So what? Well… The serializers do some magic that can yield undesired results depending on your situation. Take the following… DateTime today = DateTime . Today ; Seems harmless. If you inspect this instance further, you’ll see that the Kind is set to  DateTimeKind.Local . So, when working with the instance, it will behave in the timezone of the machine. If you serialize it on your laptop, and your laptop’s timezone is set to “Easter Standard Time” (America/New York for you Linux/Mac folks)… string json = JsonConvert . SerializeObject ( today ); Console . WriteLine ( json ); …you get… 2018-02-23T00:00:00-05:00 Notice the timezone offset. If  Dat...

Adding New Microsoft Extensions to Legacy WCF and ASMX Web Services

I was asked by several people recently: Can I use dependency injection with my legacy WCF and ASMX web services? Microsoft has some new stuff they released with core–specifically, a new configuration system, caching, and logging providers. Can I use them in my legacy WCF and ASMX web services? The answer to both is yes you can! In fact, I recommend it! To illustrate this, we’ll take a look at taking a sample application that has a WCF service and a ASMX service and we’ll: Add dependency injection using Ninject. Add the new Configuration provider from the new  Microsoft.Extensions.Configuration  packages. Add caching functionality using Microsoft’s new  Microsoft.Extensions.Caching  packages. Use the new logging providers from  Microsoft.Extensions.Logging  packages. Dependency Injection We use Ninject, but you can just as easily use AutoFac or SimpleInjector as they also have packaged integrations for WCF. You can use other containers, bu...