2025 is coming to its end. Usually, at the end of the year, it is customary to sum up everything but instead of doing so I think we can focus on the future, which essentially means – holidays and free time you can spend on reading something new and interesting – like this issue of .NET R&D Digest 🙂
This issue includes bits of AI, vibe-coding, DDD, performance, software development, testing, C#, MSBuild, diagnostics, DevOps, and of course .NET, .NET Internals and something to watch.
AI
- Vibe coding a .pdb dumper or how I became a Product Manager (by Christophe Nasarre) AI tools are becoming a standard part of the development workflow. They are used to find information,…
2025 is coming to its end. Usually, at the end of the year, it is customary to sum up everything but instead of doing so I think we can focus on the future, which essentially means – holidays and free time you can spend on reading something new and interesting – like this issue of .NET R&D Digest 🙂
This issue includes bits of AI, vibe-coding, DDD, performance, software development, testing, C#, MSBuild, diagnostics, DevOps, and of course .NET, .NET Internals and something to watch.
AI
- Vibe coding a .pdb dumper or how I became a Product Manager (by Christophe Nasarre)
AI tools are becoming a standard part of the development workflow. They are used to find information, try ideas and (of course) to generate some code. In this post Christophe Nasarre describes his journey of using the AI to write a utility to dump information about the functions from the
.pdbfiles. The post is very detailed and represents an interesting example of how you can use semi-autonomous AI to create an application without writing a single line of code. - AI Is still making code worse: A new CMU study confirms (by Rob Bowley) There is a lot of buzz inside the IT industry about the use of AI to write code faster, better and with minimal human involvement. Unfortunately, with all the hype it is quite hard to understand the real, long term impact of the AI on the project. In this post Rob Bowley shares the results of the latest CMU (Carnegie Mellon University) research of the impact of AI tools on software projects over time. Highly recommended to read if you are interested in apply the AI on the project.
SOFTWARE DEVELOPMENT
- No, Your Domains and Bounded Contexts Don’t Map 1 on 1 (by Mathias Verraes) Domain Driven Design. Saying these three words can make you a friend or foe, depending on where you say them and what you say immediately after that. Because, well, people perceive the DDD differently. However, all of them (whether willingly or not) would agree that understanding of the organisation domain and projecting it into the code to solve problem is important (but everyone also understands this part differently). In this post Mathias Verraes describes the idea that business domain doesn’t have to match one on one to bounded contexts because they are intended to be used by the different audience. The post includes a few examples and is very easy to read. Highly recommended.
- Common Performance Tuning Advice: Some Flaws (by Rico Mariani) Many modern applications have at least one dependency on an external system. Usually, communication between the application and these external systems is relatively slow (compare to the communication with internal services). So, there is a quite common opinion that you should not optimise something because “the database call takes 4 seconds, so these few milliseconds from the request itself does not matter”. In this post Rico Mariani describes how you can think about the you system as systems of queues, where every performance optimisations is something that improves the processing in a queue, which in turn might affect other queue and in combination, produce a significant and measurable effect.
.NET
- Why Do You Need To Write Architecture Tests in .NET (by Anton Martyniuk) Keeping the architecture right on the large project with the large team can be a quite challenging task – especially, if you don’t have a documentation, or a very rigid code-review process. However, if you think about the problem, then you might notice that it is very similar to the “how to ensure the class works after someone made changes to it or related ones”, which we, for a long time, solve by writing unit and integration tests. In this post Anton Martyniuk describes what “Architecture Tests” are, how you can write them and how they can help you to keep the architecture on the right track.
- Pass the State (by Szymon Kulec) When someone speaks about performance in software – it usually comes to the hardcore, low-level or niche optimisations, which sound cool when spoken but rarely met in the day to day work. So, sometimes, we tend to forget that performance in software also comes from the good quality code – when it at least avoids unnecessary allocations. In this post Szymon Kulec describes basic but so commonly overlooked issues with absolutely unnecessary state capture, and explains how to find and fix them. As always, the post is well written and easy to grasp.
- Creating a custom MSBuild SDK to reduce boilerplate in .NET projects (by Gérald Barré) Starting a new project is always a hassle – you need to configure the code style (thanks to
.editorconfigit has become much easier), include different analysers (to keep the minimal acceptable level of code quality), configure project settings – like warning as errors and so on and so forth. All these become especially important if you are creating a new project in the environment with established guidelines. In this post Gérald Barré describes how you can create a customSdkproject to automatically apply a set of sensible defaults to all new projects.
DIAGNOSTICS
- Investigating a deadlock in Visual Studio (by Kevin Gosse) All applications we write (even the simplest ones) stay on the shoulders of operating systems, system libraries, application libraries and so on. This makes even a simple console application a huge machine with a lot of moving parts, which sometimes can conflict with each other and stuck. In this post Kevin Gosse describes how he faced and debugged a deadlock in Visual Studio. The post provides a step by step description of how you can find the root cause of the deadlock by analysing the memory dump of target process. In addition to that, the post highlights interesting points about debugging in general and presents a very interesting situation, which probably would be much harder to understand without having a prior experience with such cases. Highly recommended to read.
PERFORMANCE
- Performance trick : optimistic vs pessimistic checks (by Daniel Lemire) Software performance is tricky. Mostly because the thing that is really gets executed is not exactly the thing we actually write in the code. In this post Daniel Lemire describes the difference between optimistic and pessimistic checks, and demonstrates that without a proper implementation (usually a handwritten one) even the obviously better solution might show quite bad performance.
DEVOPS
- Automatically Signing a Windows EXE with Azure Trusted Signing, dotnet sign, and GitHub Actions (by Scott Hanselman) Executing an unknown executable from the Internet is not safe. That is why Windows warns you about the potential harm and requires an explicit action to run such an executable. Which is great until you realise that any application you write and publish (without any malicious intent) will be treated in the same way. Luckily, there is a way to avoid it by signing the application. In this post Scott Hanselman describes how you can sign the application by using Azure Trusted Signing service. The post includes detailed instructions on how to configure the service and use it to sign the application locally and as part of the GitHub Actions workflow.
TIPS & TRICKS
- Resolving Overload Ambiguity with Collection Expressions (by Gérald Barré)
Method overload is a great feature of modern compilers which allows us (developers) to have multiple methods with the same name but with different set of parameters. In majority of cases, the compiler selects the correct “method” by matching it against the parameters list, which makes this feature feel so naturally. Unfortunately, sometimes, the parameters might match more than one overload, and in this case, the compiler usually yields an error. The good news is – C# compiler exposes a way to specify the priority of the method overloads. In this small tip Gérald Barré describes and demonstrates how you can use the
[OverloadResolutionPriority]attribute.
WATCH & LEARN
- Finalizers are trickier than you might think How Google Broke The Internet and Why It took 3 hours to recover? (feat. .NET Aspire) (by Sergiy Teplyakov) In the continuation of the great video series, Sergiy Teplyakov talks about potential issues you might face when implementing the finalisers for the objects wrapping unmanaged resources (great source of .NET internals by the way) and describes why even multi-service systems built for resiliency can become a victim of cascade service failures.
- .NET Aspire Beyond the Introduction (by Chris Klug) All software projects have a lot in common. Sometimes, they look so alike that it is tempting to think that they are “almost the same”. Unfortunately, in reality, all software projects have their unique moments and challenges. That is why, all great and long-living software development tools have one thing in common (pun intended) – they are extensible. In this greatly delivered presentation Chris Klug demonstrates how you can extended .NET Aspire to “natively” support development and deployment use cases. The whole presentation is a live-coding session, which is very entertaining to watch. Highly recommended.
Published by Oleg Karasik
Tech Lead at ISsoft / part of Coherent Solutions / in Minsk, Belarus. I do .NET for living and try to write code I am not be ashamed of :) View all posts by Oleg Karasik
Published December 24, 2025