Happy Monday! I hope you have a productive week and get more traction than an excavator on the Suez Canal. (Sorry.)
- One big thing: New APIs for working with dates and times
- The little things: Hot reload, debugging config settings, Clean Architecture resources
- Last week in the .NET world
One big thing: New APIs for working with dates and times
If you’re walking on the street and a person asks you the time, you can look at your watch and tell them. It’s not so simple in .NET. If you only care about the time, you need to call and parse a DateTime
or DateTimeOffset
and scrap any date information. This approach can be incredibly error-prone, as these structs carry time-zone-related logic that isn’t written for getting the absolute date and time. (That doesn’t even include its general weirdness, like DateTime.TimeOfDay
returning a TimeSpan
and DateTime.Date
returning a new DateTime
. Even on its best days, the DateTime
struct is both overloaded and confusing.)
Over on GitHub, there’s a spicy issue (with some bikeshedding) discussing the possibility of a Date
struct and a Time
struct. Initially, Microsoft chose to expose the features as an external NuGet package. However, .NET developers are looking for the changes to be in the core of the .NET BCL APIs to avoid third-party library dependencies. The issue has a proposed API.
You may see these named differently as Visual Basic has used Date
for three decades, and this would include a breaking change (and it might confuse folks using C# and VB). Right now, DateOnly
seems to be the new name. I hope this is not a permanent name.
Here’s an interesting comment from the issue about a user’s scenario:
I’m instead interested in the Date class most of all … We have a lot of products that is valid from date X to date Y. When we used DateTimeOffset we always had to remember to start at date X 00:00:00 and end at date Y 23:59:59.999. Then we switched to NodaTime and used LocalDate from there and all a sudden we could just compare dates without bother about time. We store Date in the database and map the column to a LocalDate now instead of a DateTimeOffset (which makes no sense since Date in the DB don’t have time or offset) which makes our lives even easier.
This is all developers want from their SDKs: simplicity and predictability. The excellent NodaTime library provides these capabilities, but it isn’t coming from Microsoft—which stifles adoption. It’ll be great to have simpler APIs with working with dates or times, but it might be a while before we see it in the wild. (And for the record, DateTime
isn’t going anywhere.)
The little things: Hot reload, debugging config settings, Clean Architecture resources
Say what you will about JavaScript (and believe me, I have), but it’s no mystery why it’s so widely used and adopted: the barrier of entry is low. I can open a text file, write some HTML markup (and maybe some JS), and open my web page to see the results. The instant feedback boosts productivity: in most common front-end frameworks, you can use “hot reload” functionality to see your changes immediately without having to restart the app.
That functionality is coming to ASP.NET Core (and Blazor) in .NET 6—we got a quick preview this week at Steve Sanderson’s talk at NDC Manchester. He showed off a promising prototype. Steve added and updated components (while preserving state), updated C# code, and worked well. The error handling looks nice, too—the app shows an error at the top of your page and will go away once you correct your issues and save. In some scenarios where you can’t do hot reload, your app will refresh your browser as it does now. This functionality is almost ready to show off to a larger audience—look for it in .NET 6 Preview 3, which will be released in the next few weeks.
He also showed off an ErrorBoundary
component, allowing developers to have greater control over error handling in Blazor apps. As it is today, when unhandled exceptions occur, the user connection is dropped. With this new functionality, you can wrap an ErrorBoundary
around specific markup, where unhandled exceptions in that section of code still allow users to access other parts of the app.
A month ago, our friend Cecil Phillip tweeted:
IConfigurationRoot.GetDebugView is really useful for inspecting your resolved configuration settings! 👨🏽‍💻 It's been around since .NET Core 3.0 and I never knew! 👀
docs.microsoft.com/dotnet/api/mic…
#dotnet #aspnetcore15:42 PM - 17 Feb 2021
I never knew about this, either—it helps you discover your environmental variables and settings and where they’re getting read. (And, of course, it should be used for development purposes only so you don’t accidentally leak secrets.)
When it comes to recommending architecture solutions, I use the two words that consultants live by: It Depends®. Even so, there’s a lot to like about the Clean Architecture movement.
This week, Patrick Smacchia wrote about Jason Taylor’s popular solution template. Also, Mukesh Murugan has released Blazor Hero, a clean architecture template that includes common app scenarios under one umbrella. These are both good resources on understanding Clean Architecture.
Lastly, this is exciting:
MapAction is a new way to create Web APIs without relying on Controller. (.NET 6 Preview 2)
github.com/dodyg/practica…
#aspnetcore07:51 AM - 25 Mar 2021
🌎 Last week in the .NET world
These links are new. I checked.
🔥 The Top 5
- Andrew Lock debugs configuration values in ASP.NET Core.
- Steve Gordon provides an introduction to the Roslyn APIs.
- Rachel Appel works with ASP.NET Core route templates in ReSharper and Rider.
- Ben Nadel writes about how he handles PRs on his team.
- Patrick Smacchia writes about a case study on Clean Architecture.
📢 Announcements
- The Azure SDK team provides their March update, and also announce the new Azure Event Grid client libraries.
- ReSharper 2021.1 is in beta, and so is Rider 2021.1.
- Rick Strahl goes v1.0 with his LiveReloadServer.
đź“… Community and events
- Alberto Gimeno describes how GitHub Actions renders large-scale logs.
- Check out Tess Ferrandez’s repo with some nice debugging labs.
- For community standups: ASP.NET talks about Balea authorization and Entity Framework talks about what’s new in EF Core Power Tools.
- Zack Koppert writes about solving innersource discovery problems at GitHub.
- The .NET Docs Show talks to Steve Smith about API endpoints.
🌎 Web development
- Cody Merritt Anhorn excludes files from the PWA asset cache in Blazor.
- Kevin Dockx works with OData in ASP.NET Core.
- Matthew Jones writes a Tetris game in Blazor WebAssembly.
- Damien Bowden sets dynamic metadata for Blazor Web Assembly.
- Jeetendra Gund gets HttpContext in ASP.NET Core.
- The Code Maze blog creates resilient microservices in .NET with Polly.
- Daniel Gomez Jaramillo builds an event information portal with ASP.NET Core 5.
- Claudio Bernasconi handles APIs in Blazor.
- Khalid Abuhakmeh builds a basic HTTP API in ASP.NET Core.
- Ricardo Peres warns about null models in POST requests in ASP.NET Core.
🥅 The .NET platform
- Kunal Pathak writes about loop alignment in .NET 6.
- Niels Swimberghe says: don’t use
HttpContext.Current
, especially when using async. - Peter Vogel writes about WinUI.
- David Ramel writes about Microsoft’s desktop dev options.
- Alex Klaus works with caching and environment variables.
â›… The cloud
- Paul Michaels works on Service Bus management and auto-forwarding.
- David Ramel writes about what’s next for Azure Functions.
- Johnny Reilly works with Bicep and Azure Pipelines.
- Joseph Guadagno creates a search suggestion widget using Azure Maps Search Service and KendoUI.
đź“” Languages
- Jiřà Činčura fuses await using and await foreach and await.
- Jason Roberts writes about async streams.
- Thomas Levesque wraps up his series on C# 9 records as strongly-typed IDs.
- Thomas Claudius Huber uses tuples in C# to initialize properties in the constructor and to deconstruct objects.
- Daniel B. Markham blogs about the outlines of a supercompiler in F#.
🔧 Tools
- Mark Downie collects managed crash dumps on App Services for Linux.
- Laurent Kempé calls a Dapr service with gRPC.
- Kristoffer Strube works with fake/dummy data in C# with Faker.
- Khalid Abuhakmeh adds a view to an EFCore DbContext.
- Cody Merritt Anhorn displays a Docker build version.
- Harshal Limaye writes about 20 Git commands you should know.
📱 Xamarin
- András Tóth discuss best practices for reopening apps in Xamarin.
- Charlin Agramonte animates page transitions in Xamarin Forms.
- Leomaris Reyes replicates a banking exploration UI in Xamarin.
🏗 Design, testing, and best practices
- The Software Alchemy blog works on domain-driven design entity mapping strategies.
- Derek Comartin asks: is a REST API with CQRS possible?
- Ashley Davis scales microservices on Kubernetes.
- Priyanka mocks with LINQ to unit test in ASP.NET Core.
🎤 Podcasts
- The .NET Rocks podcast talks to Mads Kristensen about Visual Studio feedback.
- The .NET Core Show discusses emulating a video game system in .NET with Ryujinx.
- The Azure DevOps Podcast talks to Richard Campbell on the history of .NET.
- The Coding After Work podcast talks to Carl Rippon about React, books, and Blazor.
- The 6-Figure Developer podcast talks to James Avery about designing for scale.
- The Adventures in .NET podcast talks to Jason Bock about C# 9.
- The Azure Podcast talks about learning Azure SQL.
🎥 Videos
- The Visual Studio Toolbox talks to Sam Basu about desktop development choices.
- At Technology and Friends, David Giard talks to Jason Farrell about Kubernetes.
- Azure Friday discusses best practices for Azure Container Instances (ACI) with GitHub Actions.
- The On .NET Show talks about C# source generators and cloud native patterns.
Top comments (0)