ASP.NET Core logging with Serilog
Part of my ASP.NET Core recipe series: replacing the default logging with Serilog for structured logs with proper sinks.
The journal
149 articles on building software and understanding how it works.
Part of my ASP.NET Core recipe series: replacing the default logging with Serilog for structured logs with proper sinks.
The opening recipe in my ASP.NET Core series: setting up a clean MVC project as the foundation the rest of the recipes build on.
Plugins for a .NET Core app boil down to loading .dlls at runtime, finding the interesting interfaces and registering them in IoC. Since IoC already gives you loose coupling, dynamic loading is a small step — shown here.
MVC gets IoC boilerplate generated for free; console apps don't. With HostBuilder from the Generic Host it's easy to wire up the same dependency injection, config and logging in a console application — here is the boilerplate.
Interface, base class, virtual, override, dynamic, reflection or expression trees — .NET gives you many ways to call a method, and their costs differ wildly. Full benchmark with numbers for each.
Part 2 of the voxel engine introduction: turning chunk data into renderable polygon meshes in Unity, one Mesh per chunk, and only drawing the faces that can actually be seen.
My Christmas vacation project: a basic introduction to voxel engines à la Minecraft. Part 1 covers what voxels are, polygon meshes, and how to represent a voxel world in memory without hitting limits.
Unity happily lets you write C# but not structure it. Four ways to share code between proper Visual Studio projects and Unity — so your libraries stay testable and your Unity project stops being a big ball of mud.
After ~30 years and a few thousand projects, this is how I set up new .NET solutions: naming, project structure, .NET Standard vs Core choices — and the reasoning behind each habit. Not a book on architecture, just a clean, consistent setup.
sizeof() compiles to a constant; Marshal.SizeOf() measures the marshaled struct at runtime. What each one really returns, what it costs, and when to use which — with IL to prove it.
What does a method that just calls another method actually cost? Using the == operator vs IEquatable.Equals as the guinea pig, I benchmark wrapper calls across compilers, JITs and runtimes — and read the disassembly to see why.
Unity's Vector2/3/4 and Quaternion lack IEquatable and have a poor GetHashCode, which quietly murders performance the moment you put them in lists or dictionaries. Measurements, explanation, and the fix I reported to Unity.
Reading appSettings shouldn't require custom sections, XML readers or per-access string conversion. A small base class that maps keys like Config.SmtpClient.Host to a typed tree, converted once at startup.
CsvHelper is great, but writing the model and mapper classes is tedious. Paste your CSV header on this page and it generates both classes for you.
Redirecting all HTTP to HTTPS in IIS breaks Let's Encrypt's renewal challenge. Two URL Rewrite rules fix it: let .well-known through, redirect everything else.