<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>.NET on Artur Rios Lab</title><link>https://artur-rios.github.io/personal-lab/dotnet/</link><description>Recent content in .NET on Artur Rios Lab</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Wed, 21 Oct 2026 19:30:00 +0000</lastBuildDate><atom:link href="https://artur-rios.github.io/personal-lab/dotnet/index.xml" rel="self" type="application/rss+xml"/><item><title>How I Develop APIs</title><link>https://artur-rios.github.io/personal-lab/dotnet/how-i-develop-apis/</link><pubDate>Wed, 21 Oct 2026 19:30:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/dotnet/how-i-develop-apis/</guid><description>&lt;p&gt;Every backend I build is an ASP.NET Core API, and they all look alike on&#10;purpose. When the structure is the same everywhere, I never have to remember&#10;where a thing lives, a new feature is a list of files to add rather than a&#10;design decision, and a test that fails points at one small piece of code.&lt;/p&gt;&#10;&lt;p&gt;This page describes that shape, using&#10;&lt;a href="https://artur-rios.github.io/heimdall-api/"&gt;Heimdall&lt;/a&gt; as the example&#10;throughout. Heimdall is my identity management API: people, applications,&#10;logins, two-factor authentication and permissions, for several client systems&#10;at once, each in its own scope. It is the largest API I have, so every pattern&#10;here has been tested against a real use case rather than a toy one. All code&#10;on this page is taken from it, trimmed only where noted.&lt;/p&gt;</description></item><item><title>The .NET Libraries I Reach For</title><link>https://artur-rios.github.io/personal-lab/dotnet/library-recommendations/</link><pubDate>Wed, 21 Oct 2026 13:20:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/dotnet/library-recommendations/</guid><description>&lt;p&gt;Every new .NET project starts with the same handful of decisions. How will I&#10;test it? Where does fake data come from? How do I validate input, survive a&#10;flaky dependency, export a spreadsheet, run something every night? The base&#10;class library answers some of these. For the rest, I have settled on a short&#10;list of NuGet packages that I add almost without thinking.&lt;/p&gt;&#10;&lt;p&gt;This page is that list, with the reasoning written down. For each library I&#10;explain what it is for, why I use it, show a small example and say when I&#10;would pick something else. A recommendation is only as good as what it&#10;leaves out, so I also flag what I would want to know before adding a&#10;dependency: licence, maintenance, breaking changes, and in two cases events&#10;that every user of the library should know about.&lt;/p&gt;</description></item><item><title>Test Coverage in .NET: What It Measures and How to Collect It</title><link>https://artur-rios.github.io/personal-lab/dotnet/test-coverage/</link><pubDate>Wed, 21 Oct 2026 13:10:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/dotnet/test-coverage/</guid><description>&lt;p&gt;A pull request comes back with a comment: &amp;ldquo;coverage dropped from 84% to 81%&amp;rdquo;.&#10;What does the number mean? Which 3% went missing, and does it matter? Coverage&#10;is one of the few test metrics that every .NET tool can produce for free, and&#10;one of the easiest to misread. It is very good at answering &lt;em&gt;which code did no&#10;test run?&lt;/em&gt; and close to useless at answering &lt;em&gt;are the tests any good?&lt;/em&gt;&lt;/p&gt;</description></item><item><title>EF Core or Dapper? Two Ways to Talk to a Database from .NET</title><link>https://artur-rios.github.io/personal-lab/dotnet/ef-core-and-dapper/</link><pubDate>Wed, 21 Oct 2026 13:00:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/dotnet/ef-core-and-dapper/</guid><description>&lt;p&gt;Almost every .NET application that stores data ends up choosing how its C#&#10;code will talk to a relational database. Two names come up more than any&#10;other. &lt;strong&gt;Entity Framework Core&lt;/strong&gt; is Microsoft&amp;rsquo;s object-relational mapper: you&#10;describe your classes, and it writes the SQL, tracks what you change and&#10;evolves the schema. &lt;strong&gt;Dapper&lt;/strong&gt; is a small library from Stack Overflow: you&#10;write the SQL, and it turns the rows that come back into objects.&lt;/p&gt;</description></item><item><title>C# Delegates: Methods as Values</title><link>https://artur-rios.github.io/personal-lab/dotnet/delegates/</link><pubDate>Wed, 21 Oct 2026 12:50:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/dotnet/delegates/</guid><description>&lt;p&gt;&lt;code&gt;List&amp;lt;T&amp;gt;.Sort&lt;/code&gt; doesn&amp;rsquo;t know how you want your items ordered, so it asks you:&#10;pass it a method that compares two items, and it calls that method whenever it&#10;needs to. A button doesn&amp;rsquo;t know what should happen when it is clicked, so it&#10;keeps a list of methods to call. LINQ&amp;rsquo;s &lt;code&gt;Where&lt;/code&gt; doesn&amp;rsquo;t know which items you&#10;want, so it takes a method that answers yes or no for each one. All three&#10;need the same thing from the language: a way to treat &lt;em&gt;a method&lt;/em&gt; as a value&#10;that can be stored in a field, passed as an argument and called later. In C#&#10;that value is a &lt;strong&gt;delegate&lt;/strong&gt;.&lt;/p&gt;</description></item><item><title>IEnumerable, ICollection, IList and IQueryable: What Each Collection Interface Promises</title><link>https://artur-rios.github.io/personal-lab/dotnet/collection-interfaces/</link><pubDate>Wed, 21 Oct 2026 12:40:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/dotnet/collection-interfaces/</guid><description>&lt;p&gt;Open almost any C# codebase and you will find method signatures that take an&#10;&lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt;, entities with &lt;code&gt;ICollection&amp;lt;T&amp;gt;&lt;/code&gt; navigation properties,&#10;repositories returning &lt;code&gt;IQueryable&amp;lt;T&amp;gt;&lt;/code&gt;, and the occasional &lt;code&gt;IList&amp;lt;T&amp;gt;&lt;/code&gt; or&#10;&lt;code&gt;IReadOnlyList&amp;lt;T&amp;gt;&lt;/code&gt;. They are easy to treat as interchangeable names for &amp;ldquo;a bunch&#10;of items&amp;rdquo;, and the code usually compiles whichever one you pick. Yet each&#10;interface makes a different promise, and choosing the wrong one causes real&#10;bugs: a query that runs three times, a database table loaded into memory to be&#10;filtered in C#, an exception thrown far from the line that caused it, or a&#10;&amp;ldquo;read-only&amp;rdquo; list that changes under your feet.&lt;/p&gt;</description></item><item><title>How C# Runs: From Source to IL to Machine Code</title><link>https://artur-rios.github.io/personal-lab/dotnet/compilation-and-execution/</link><pubDate>Wed, 21 Oct 2026 12:30:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/dotnet/compilation-and-execution/</guid><description>&lt;p&gt;A C# program is not compiled straight to machine code, and it is not&#10;interpreted either. It is compiled &lt;strong&gt;twice&lt;/strong&gt;. When you build, the C# compiler&#10;turns source code into an intermediate language and a description of every&#10;type, packed into an assembly, a &lt;code&gt;.dll&lt;/code&gt; file. When you run, the .NET runtime&#10;turns that intermediate language into machine code for the CPU it is running&#10;on, usually one method at a time and often more than once as it learns which&#10;code is hot.&lt;/p&gt;</description></item></channel></rss>