Most Active Speaker

Dennis Doomen

Dennis Doomen

Hands-on architect in the .NET space with 26 years of experience on an everlasting quest for knowledge to build the right software the right way at the right time

The Hague, The Netherlands

Dennis works for Aviva Solutions, is a Microsoft MVP and a veteran hands-on architect in the .NET space with a special interest in writing clean code, Domain Driven Design, Event Sourcing and everything agile. He specializes in designing enterprise solutions based on the .NET technologies as well as providing coaching on all aspects of designing, building and maintaining enterprise systems. He is the author of https://www.fluentassertions.com, a very popular .NET assertion framework, https://www.liquidprojections.net, a set of libraries for building Event Sourcing architectures and he has been maintaining coding guidelines for C# on https://www.csharpcodingguidelines.com since 2001. He also keeps a blog on his everlasting quest for better solutions at https://www.continuousimprover.com. You can reach him on Twitter through https://twitter.com/ddoomen and on Mastodon through https://mastodon.social/@ddoomen.

Awards

Area of Expertise

  • Information & Communications Technology

Topics

  • .net
  • agile
  • Domain Driven Design
  • eventsourcing
  • Test-Driven Development
  • Unit testing
  • architecture
  • dotNet
  • dotnet core
  • Clean Code
  • .net core
  • Event Sourcing
  • .NET Patterns & Practices
  • Visual Studio / .NET
  • CQRS & Event Sourcing
  • CQRS
  • Test Automation
  • Software testing
  • Agile Testing
  • .NET Backend
  • ASP.NET Core
  • .net 6
  • java
  • Software Testing & QA
  • DevOps

My 25 Laws of Test Driven Development

About 15 years ago, I got inspired by the practice of Test Driven Development. Now, with many years of great and not-so-great experiences practicing Test Driven Development, I thought it is the time to capture my own “laws”. The term "law" is obviously an exaggeration and "principles or heuristics" cover my intend much better. Either way, I want to talk about the scope of testing, using the observable behavior, naming conventions, state-based vs interaction-based testing, the impact of DRY, patterns to build useful test objects and some of the libraries and tools I use. In short, everything I try to follow every day I write, review or maintain code.

10 years of Event Sourcing; thoughts and experiences

Having designed, build and run systems that are deployed on oil platforms all over the world and that use Event Sourcing as their underlying architecture means that I've experienced all the greatness and the pains this architecture style has to offer. In this talk, I'm going to share you my experiences with over 10 years of practicing Event Sourcing in multiple systems. I'll talk about the reasons we adopted it in the first place, the challenges we had introducing this to the developers, the problems we ran into in production, and the lack of confidence we got from management. I'll conclude this talk with my current thoughts on Event Sourcing and how I would implement it when I would have to do it again.

50 reasons why JetBrains Rider made me a more efficient C# developer

As long as I’ve been developing in C#, I remember I’ve been looking for add-ons to make me more productive. In 2004, I discovered JetBrains’ ReSharper for Visual Studio. It improved Intellisense, the coloring of identifiers, the many built-in refactorings, it felt like a new world opened up to me. But I also noticed that with every new Visual Studio and ReSharper release the memory and CPU footprint increased a lot. In 2016, JetBrains announced Rider, a full-blown IDE for .NET and C# developers based on there wildly successful IntelliJ IDE and all the power of ReSharper. By the end of 2017, I fully switched to Rider and I never looked back.

Since then, the competition has been running behind more and more. By now, Rider is the most refined IDE you can wish for, and the improvements and features just keep coming and coming. Think of things like a predictive debugger, a very powerful integrated Git client (supporting interactive rebased), unrivaled code navigation and refactoring options and a solution-wide code analysis. So in this talk, I'd like to show you at least 50 reasons why Rider made me more productive

What you can learn from an open-source project with 300 million downloads

After more than 10 years of development, our pet project, Fluent Assertions has almost reached the 250 million downloads. Providing a high quality library like that doesn't come for free. We've been trying to write code that is clean enough for our contributors, write tests that are self-explanatory, ensure breaking changes are strictly controlled and try to make it easy to use.

In this talk, I'd like to share the tools and techniques we have been using, how they've enriched our day jobs, and how they may do that for you too.

I'll talk about the release strategy, documentation, versioning, naming conventions, code structure, the build pipeline, automated testing, code coverage, API change detection, multi-targeting and more.

Covers: GitVersion, GitFlow, semver, Chill, test naming conventions, Nuke, GHA, Coverlet, Approval Tests, GH release notes, Jekyll/Minimal Mistakes, multi-targeting, C# 10, Rider, Jetbrains Annotations, editorconfig/Stylecop, TDD, design guidelines, decision logs, mutation testing

Getting a grip on your code dependencies

I'm sure every developer wants to be able to change code with confidence and without fear. Readable and self-explanatory code is one aspect of that. Too much coupling is another major source of problems that prevent you from changing one part of the system without causing side-effects. In this talk, I'd like you to show you common sources of unnecessary coupling and offer you options to help prevent and/or break those. I'll talk about how principles like Don't Repeat Yourself and Dependency Injection can be a double-edge sword, how to detect too unnecessary dependencies and how to use the Dependency Inversion Principle to unravel some of those. And yes, I will also talk about controlling dependencies on the package level.

@law of demeter
@using DRY
@Using DIP
@Dealing with ugly dependencies by applying DIP and an adapter
@SQ rule to detect too many dependencies
@Dependency management at the package level
@Dependency injection is great, but try to avoid a global container
@ASP.NET core at the module level

Common pitfalls of Event Sourcing and how to address them

Plenty of great content has been written about the problems Event Sourcing can help you solve. But after almost 10 years of using Event Sourcing in a distributed occasionally connected environment, I've experienced a lot of real-world challenges. In this talk, I'm going to talk about common challenges I've run into and the options I use to address them. I'll cover aggregate boundary challenges, problems finding the invariants, cross-domain communication, value types and events, versioning of events, eventual consistency of projections, projection bugs, time to rebuild projections, supporting blue/green deployments and more.

16 practical design guidelines for successful Event Sourcing

A couple of weeks ago I ended up in a technical debate on how to take an existing Event Sourced application further to fully reap the benefits it is designed to give you. I’ve written many posts about the pitfalls, the best practices and how to implement this in .NET specifically. But after 10 years of Event Sourcing, I still think it is useful to provide you with a list of the most important guidelines and heuristics that I think are needed to be successful with Event Sourcing. I'll talk about aggregate boundaries, appropriately-sized events, cross-domain communication, optimizing projection speed, aggregating data and more.

10 problems that Event Sourcing can help you solve

I regularly end up in a discussion on whether Event Sourcing is the right architecture style or not. As the universal answer to this question tends to be “it depends”, I started thinking about the typical problems where I would use Event Sourcing. With about 10 years of experience building and running Event Sourced systems, I came up with 10 examples of where Event Sourcing shines, some more functional and some more technical.

What is the right "unit" in unit testing and why it is not a class?

Whether you're just writing your first unit test or have been practicing Test Driven Development for many years, I'm sure your biggest challenge is to find the right scope for testing. Unfortunately a lot of books and guidance seem to imply that every class or type should be tested separately. Well, I can tell you from 15 years of unit testing experience that that's the best way to shoot yourself in the foot.

In this session, I'm going to show you some concrete examples and why I chose a certain boundary for the "unit" in unit testing. I will also share design heuristics I use myself to find those boundaries and why those are not guidelines. I'll also illustrate how principals like DRY and SOLID can be both a blessing and a curse that may lead to the wrong design choices.

It gives the audience food for thought on how the internal boundaries of your architecture can influence the scope of automated testing, how different layers of testing are complimentary, and why the "class-as-a-unit" is often wrong.

Using C# and Nuke to create build & deploy pipelines that you can test, debug and refactor

I've had a lot of prior build automation experience with the XML hell of MSBuild, the PowerShell sizzle of PSake and the "feels like C# but doesn't quite act like it is" Cake approach, both in my open-source projects as well as in professional projects. But nothing has made it such a sweet and smooth experience as Nuke did. The idea of using C# and .NET Core for build scripts that Cake introduced was a great idea, but because it didn't adopt C#/.NET fully, it became a painful exercise of plain text editing. I've been using Nuke for a while and it solved all of those concerns in a very well designed way. To show you why I think this is true, let me show you why Nuke is such a blessing for those that treat their build scripts as first class citizens of their code base.

The strengths and weaknesses of dependency injection

Concepts like the Dependency Inversion Principle, Inversion of Control containers and Dependency Injection libraries are often mixed up, but they are not the same. You shouldn’t use a DI library until you understand the problems your solving, nor is it always the best solution.

Since I’ve felt this pain many times myself, I’d like to use this session to create some clarity. First, I’ll demonstrate the reason why people typically use libraries like Unity and Autofac in their code bases. Then I’ll show you that those same people often use the Dependency Inversion Principle in the wrong way (and need to revert to mocking libraries to compensate). Then I’ll show you how to apply the principles properly by carefully designing the seams in your architecture. And finally, I’ll show you how an advanced library can connect the dots in a very elegant way.

Software architecture lessons I learned from my latest monolith

After having been in charge of building a large distributed enterprise-ready web-based system for over seven years, it is time to reflect on that period and share some of the most important lessons I've learned on software architecture and agile software development within the .NET realm. Could I have avoided the monolith in the first place? And what about domain modeling, technical design principles and design patterns? Do they still have merrits? And don't forget .NET coding practices, testing practices, data management and deployment techniques. In other words, what do I think I should do again or differently the next time I need to design a complicated high-performance system.

Slow Event Sourcing reprojections? Just make them faster!

I don't have to tell anybody how awesome Event Sourcing is as an architecture style. But those that have been using it in production must have experienced the pains of keeping the upgrades fast enough, especially if you use a more traditional relational database like SQL Server. I've once heard somebody say: "If it's slow, make it faster", but rebuilding a big projection is simply a very expensive operations and involves a lot of network traffic between the application and the database servers.

Over the years since we adopted Event Sourcing, we've been experimenting a lot and have implemented various improvements to make those reprojections faster. And we haven't stopped. We're already working on some new ideas lately. So in this session, I'd like to share those techiques, their pros and cons and how we implemented them on a more detailed level.

How to automate your infrastructure using Pulumi and C#

Who remembers the days were you had to manually setup a physical server somewhere in a 19 inch rack? Nowadays those physical racks have been replaced by virtual machines provided by Google, Microsoft and Amazon. But some people are still provisioning them manually. The more mature organizations will script most of the provisioning using the native CLI or HTTP API provided by the specific cloud platform, but quite often those are maintained separately from the code of the system that is being deployed. Terraform by Hashicorp is another attempt to support infrastructure-as-code by using a declarative syntex to define the desired infrastructure. But then again, Yaml isn't really suited for anything but simple single-file configuration settings. Yaml isn't code and doesn't provide real Intellisense, line-by-line debugging and most importantly, refactoring.

But what if you could use C# and .NET to provision your infrastructure and treat that code as first-class citizens of your codebase, including all the capabilities that you would expect? Well, let me show you how Pulumi for .NET will allow you to evolve your infrastructure code with the rest of the code base without turning it in a big spaghetti of Yaml files.

How to write unit tests without shooting yourself in the foot

It's 2022, so practices like Test Driven Development (TDD) have long found their way into organizations. However, the practices and principles to keep those unit tests maintainable haven't really changed. Still, I regularly talk to developers that somehow ended up with an incomprehensible unmaintainable set of unit tests that they once believed in, but are now holding them back. So in this session I like to provide a refresh of those fundamental ideas and talk about why you should practice TDD, revealing intentions, naming conventions, state versus interaction based testing, and how to stay out of the debugger hell with proper mocking and assertion frameworks. And even if you believe you are well versed in the testing realm, join me anyway.

Lessons learned from 27 years of professional software development

I recently was asked what I would do differently if I had the experience I have now. This got me thinking about the mistakes I've made, the traps I fell for and the dogmatism I became part of over the last 27 years of professional software developer in the Microsoft realm. In this talk, I'll be going down memory lane with you and share everything I've learned on architecture, tools, technologies, agile software development, maintainable code, automated testing, documentation and anything else that I think you should know. Prepare yourself for a full hour of stories, both good and bad.

Event Sourcing Done Right - Experiences from the Trenches

Over the years I've spoken many times about what Event Sourcing is and shared many of the good, the bad and the ugly parts of it in blog posts and various talks. However, I've never talked about how to actually build a system based on this architecture style. I keep getting the same questions over and over again. Like when to apply Event Sourcing and at what architectural level. How to deal with transactional boundaries within and outside the domain. How to build projections that are autonomous, reliable and self-supporting. How to deal with upgrades and blue-green deployments. But also on how to handle bugs, design mistakes and crashing projections. Having made a lot of these mistakes myself over these years, it's time to share my current thoughts and opinions about this. Since the .NET space has a pretty rich set of open-source projections to support this, the examples and code will be .NET. But the concepts are universal, so don't let that scare you off.

Design heuristics that make you a better software developer

Over the years, I've noticed that a lot of architectural decisions that I make are based on gut feelings. You know that feeling when you've heard some of the details and angles on a problem, you start to build up this direction in the back of your mind? It's never perfect, but gives you a general feeling of how to approach the problem? Well, I've also learned that these are design heuristics, principles and guidelines that don't always apply, don't guarantee a solution, but are enough to get you going. With almost 24 years of (professional) experience, I'd like to share the design heuristics I use in my day to day job as a software architect. It won't solve all your problems, but give you enough tools to get you going on your next assignment.

Build libraries, not frameworks

Frameworks are supposed to help you build things more quicker and hide a lot of complexity around cross-cutting and infrastructural concerns. They are supposed to make it easier for inexperienced developers to join a running projection. But frameworks also introduce a lot of magic, and that magic is going to backfire at some point. At least, that's my experience. And when it backfires, your code is so entangled with that framework, that you can't get rid of it anymore.
So, instead of building and using frameworks, build and use libraries. That's easier said then done, so let me share some of the practices I use to build composable libraries myself. I'll talk about principles of package design and scoping, keeping your NuGet package dependencies in check, and how to use layered APIs to increase usability without hiding the magic.

A practical introduction to DDD, CQRS & Event Sourcing

After several in-depth talks about Event Sourcing, I realized that there's a large group of developers that may have heard about Domain-Driven Design, Command-Query Responsibility Segregation and Event Sourcing, but have not really connected the dots yet. So in this talk, I'd like to take a practical example of a simple domain and gradually introduce functional requirements to see how the principles behind DDD affect the way your entities are going to protect the business rules. After that, I'll introduce some real-world non-functional requirements and see if and how Event Sourcing and/or CQRS may or may not help to accomplish those.

30 things that a software development should not be doing

Enough books have been written, articles have been published and Youtube videos have been posted about how you should be behaving as a software developer, Scrum Master or team lead. To be original in this unoriginal world, I started thinking about the things you should NOT be doing. I came up with 30 tools, practices and principles covering topics like dealing with complexity, productivity, architecture, testability, traceability, maintainability, transparency and predictability that I believe hamper you as a professional. That sounds like a lot, but I promise you a fun and entertaining session that I'm sure will trigger a lot of recognition.

A lab around the principles and practices for writing maintainable code

Writing maintainable code is not something that is easy to do. Not only is a pretty subjective, a lot of the techniques like Clean Code, SOLID and such can be misinterpreted resulting in unconstructive dogma. I've made it my career's goal to find a good balance between all those different patterns, principles, practices and guidelines. In this talk, I like to share you my own ideas on what it takes to write maintainable code. I'll talk about architecture, class design, automated testing and any consequences on your development process. If you care about your code, be there with me.

Tools and practices to help you deal with legacy code

We all love to build greenfield projects, but the reality is that in most jobs you have to deal with a lot of legacy code. This doesn't mean the code is bad. It just means that choices were made that were the right ones at that time, or that the developers were not entire up-to-date with modern development practices. And that's exactly what this talk is about. I enjoy taking such a codebase and gradually introduce architectural seems, add a proper build pipeline, introduce temporary tests and then gradually refactor the codebase to combine more maintainable, testable and reliable. So in this talk, I'd like to unfold my extensive toolbox of practices, principles, tools and mindset to help you improve your legacy code without jeopardizing your business. Most of it will be .NET focused, but quite a few also cover JavaScript/TypeScript.

Covers topics like this

• Characteristics tests
• A proper IDE like Rider to
○ detect code inefficiencies and dead code
○ render project diagrams
○ Quickly navigate
• Editorconfig / eslint so auto-format works
• Nuke build pipeline to get consistency
• GitHub actions build
• Adopt a version strategy and name branches accordingly
• Adopt automatic versioning using Github
• Add API verification tests
• Functional folder structure
• Architecture slide
• Enable nullable types per file
• Reduce the scope of types and members to find more dead code
• Move new code to .NET Standard projects or cross-compile
• Switch to SDK-style csproj
• Add scripts or builds steps to run the code locally
• Pulumi to automate PR deployments
• Adopt structered logging
• Use Dependency Injection
• Introduce interfaces and delegates without going overboard
• Add architecture dependency frameworks
• C4 Model
• Use test containers

Lap around the AI tools I use to be more productive as a software developer

These days, Artificial Intelligence is everywhere and has had a huge influence on our world. As a developer, there are now numerous AI tools available to improve your productivity. You can look at them with fear, but you can also, as I now do, fully embrace them and use them as tools to make yourself even more productive.

In this hands-on session without too many slides, I want to show you which tools I currently use and what I actually do with them in my daily life as a software developer.

22 reasons for switching from Azure DevOps to GitHub

As an open-source maintainer for over 15 years, and an open-source project with over 300 million downloads on NuGet, I like to believe I know what it takes to have large numbers of people contribute to a code-base efficiently. Next to that, I've been a consultant for almost 27 years helping organizations to get the most out of modern software development efforts. As such, I regularly work with Azure DevOps (AZDO), GitHub and even BitBucket and have been able to experience their differences first-hand. In this talk, I'm going to give you 22 reasons why you should switch to GitHub.

Using Boundary-Driven Development to beat code complexity

As developers we are trained to apply principles like SOLID, Unit Testing and DRY, are lured into adopting certain architecture styles such as Event Sourcing or Clean Architecture, and are influenced to move away from monoliths to microservices. The truth is that all of these have value, but all can be applied the wrong way resulting in the opposite effect.

I believe that understanding or carefully designing the internal boundaries of your code base is the key ingredient to prevent that notorious Big Ball of Mud. This is not a trivial feat, so in this talk I will show you why I believe the importance of boundaries and provide you with heuristics and examples to (re)design your own boundaries to end up with a healthy codebase, whether you prefer to keep that monolith or go for a microservices approach.

• Help find the unit of testing
• Help find the scope of a DI container
• Help find applying DRY with causing coupling
• Help determine when to use an abstraction and when not
• Helps to figure out which architecture to use where
• Code that isn't supposed to be reused doesn't have to be in its own class.

15 years of insights from a TDD practitioner

Unit Testing and its more proactive version Test Driven Development have both opponents as well as proponents. And I get why. It's not easy to do, and if you do it wrong, it hurts. I've shot myself in the feet more than once. But if you do it right, you'll never want to go back to a situation where you don't write tests for all your code. That's what let me to create Fluent Assertions and become the maintainer of ChillBDD.

But TDD doesn't mean you really need to write all tests upfront. The reality is much more pragmatic than the books like you to believe. And this isn't just about test code. A big chunk (if not all) of unit testing and TDD is about designing your solution to be testable.

In this talk I'll share everything I've learned over 15 years of practicing Test Driven Development.

Covers topics like
* The value of unit testing and TDD
* How to be pragmatic with TDD
* How archiecture and code design affects testability
* How to find the right scope of testing
* Tips to write tests that are self-explanatory

Partially based on
* https://www.continuousimprover.com/2023/04/unit-testing-scope.html
* https://www.continuousimprover.com/2021/10/laws-test-driven-development.html

Developer Week '24 Sessionize Event Upcoming

July 2024 Nürnberg, Germany

NDC Sydney 2024 Sessionize Event

February 2024 Sydney, Australia

NDC London 2024 Sessionize Event

January 2024 London, United Kingdom

Bitbash 2024 Sessionize Event

January 2024 Veenendaal, The Netherlands

FreshMinds

Practical introduction to DDD, CQRS & Event Sourcing

January 2024 Leiden, The Netherlands

.NET Zuid

Lap around the AI tools I use to be more productive as a software developer

January 2024 Best, The Netherlands

Swetugg Gothenburg 2023 Sessionize Event

October 2023 Göteborg, Sweden

NDC Porto 2023 Sessionize Event

October 2023 Porto, Portugal

Techorama Netherlands 2023 Sessionize Event

October 2023 Utrecht, The Netherlands

Developer Week '23 Sessionize Event

June 2023 Nürnberg, Germany

NDC Oslo 2023 Sessionize Event

May 2023 Oslo, Norway

Craft Conference 2023

My 19 Laws of Test Driven Development

May 2023 Budapest, Hungary

Code Europe 2023

Getting a grip on your code dependencies
What is the right "unit" in unit testing and why it is not a class?

May 2023 Kraków, Poland

DOTNED SATURDAY 2023 Sessionize Event

May 2023 Hilversum, The Netherlands

.NET Conf 2022 1nn0va Sessionize Event

January 2023 Pordenone, Italy

.NET Developer Conference '22 Sessionize Event

November 2022 Köln, Germany

Update Conference Prague 2022 Sessionize Event

November 2022 Prague, Czechia

KanDDDinsky 2022 Sessionize Event

October 2022 Berlin, Germany

Developer Week '22 Sessionize Event

July 2022 Nürnberg, Germany

Future Tech 2022 Sessionize Event

June 2022 Utrecht, The Netherlands

DOTNED SATURDAY 2022 Sessionize Event

May 2022 Hilversum, The Netherlands

DotNED

March 2022 Alphen aan den Rijn, The Netherlands

.NET Developer Conference '21 Sessionize Event

November 2021 Köln, Germany

Dotnetdays Romania

February 2020 Iaşi, Romania

DDD Europe 2020

February 2020

Domain-Driven Design Europe 2020 Sessionize Event

February 2020 Amsterdam, The Netherlands

DDC Conference

November 2019 Köln, Germany

Bay Area .NET User Group

November 2019 San Francisco, California, United States

KanDDDinsky Sessionize Event

October 2019 Berlin, Germany

TestCon Europe 2019

October 2019 Vilnius, Lithuania

Techorama Netherlands 2019 Sessionize Event

October 2019 Ede, The Netherlands

Riga Dev Days

May 2019 Riga, Latvia

Newcrafts Paris

May 2019 Paris, France

MicroCPH Copenhagen

May 2019 Copenhagen, Denmark

KanDDDinsky Sessionize Event

October 2018 Berlin, Germany

Techorama NL 2018 Sessionize Event

October 2018 Ede, The Netherlands

Dennis Doomen

Hands-on architect in the .NET space with 26 years of experience on an everlasting quest for knowledge to build the right software the right way at the right time

The Hague, The Netherlands