C# Namespace Fever

thebuzzsaw

Kelly Brown

Posted on May 28, 2023

C# Namespace Fever

Alright... I'm done chopping my code into microscopic namespaces. There's just no point. All it does is force a bunch of using statements all over the code (both in the project itself and in any project consuming it as a library).

The most common place I see this unhealthy obsession is in your typical ASP.NET app. Devs feel this compulsion to make a namespace for every kind of component.

namespace MyApp.Web.Controllers;
namespace MyApp.Web.Models;
namespace MyApp.Web.Services;
namespace MyApp.Web.Utils;
Enter fullscreen mode Exit fullscreen mode

And this is a kind representation. I've even seen projects isolate Models.Request from Models.Response. Personally, I do not think this is necessary or helpful. In my more recent endeavors, I've settled on just using MyApp.Web and stopping there. It gets rid of a ton of useless using statements, and all the identifiers I need are now properly visible. I still find it acceptable to put the other whole layers into separate namespaces (MyApp.Domain, MyApp.Repository, etc.).

I fell prey to this in Jawbone. I think there is just something alluring about "being as cool as the .NET base classes". Hey, .NET has a namespace for its collections, so I should have a namespace for my collections! There's just one problem, though: .NET is huge, and my library is not. When you reach a certain size, it makes sense to gently categorize various components. Also, if code exists in distinct projects, having a different namespace makes sense.

So, I've taken the first steps to wrangling this mess. I am eliminating the Piranha.Jawbone.Tools and Piranha.Jawbone.Collections namespaces. In my mind, there are only two scenarios that justify a new namespace:

  1. Strongly distinct domains: I am keeping namespaces such as Piranha.Jawbone.Sqlite and Piranha.Jawbone.Sdl. Those are highly cohesive domains that could arguably even be spun off into their own libraries if the need arose. They revolve around major native components and have clear delineation.
  2. Isolation of extensions on common datatypes: if I want to introduce extensions for common types like string or DateTime or whatever, I don't want those extensions flooding devs' autocomplete. It's polite to let them opt in by using Piranha.Jawbone.Extensions. They should not pay that price just for using Piranah.Jawbone. Meanwhile, for new datatypes introduced by Jawbone itself, the extensions just sit in the Piranha.Jawbone namespace.

Already, I am enjoying the drastic reduction in using statements.

💖 💪 🙅 🚩
thebuzzsaw
Kelly Brown

Posted on May 28, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related