I’ve spent a lot of time over the past few years working on multi-developer projects. It’s incredibly important that you ensure that the pit of success is large for other developers. Obviously there will always be a learning experience, which hopefully can be alleviated through pairing and / or decent developer documentation, either through test suites or wiki etc.. But a large part of making a framework discoverable is in choosing the namespaces correctly. I’m talking here about the dreaded “.Core” or “.Framework” areas e.g.
What purpose does this extra “Core” give us? Absolutely nothing! The worst part about something like this is that it only serves to obfuscate the most common parts of your system instead of making them as easy to find as possible. And yet I see it time and time again, on one project after another.
The problem with Framework namespaces
Why is this a problem? Imagine you’re a developer working on some part of the system. Perhaps you’re coding a service that lives in a namespace like Company.App.Services e.g. Company.App.Services.CustomerService. Why should you, as a consumer of the framework, have to know about adding a using statement (or similar) to Company.App.Core.Services in order to use ServiceBase or similar? The answer is – you shouldn’t!
Intellisense should be able to present you with common types as soon as you tell it what you are working on, be it a service, or repository (which I hate – more on that in another post) or whatever else. How do you tell Intellisense what you are working on? By what namespace you’re in. Your core types should live in the same logical namespace as the most likely namespace for consumers of that type. ServiceBase should live in Company.App.Services because this is where your actual services live.
There’s a subtle difference between physical deployment – where framework classes are slowly changing and probably should live outside of the day-to-day changing business code (particularly when writing modular, pluggable code) – and logical namespaces where many types can live across many physical assemblies in that namespace without a problem.
There’s also an oft-repeated mantra that says that your assemblies should be named after the namespaces that they live in. This is fine – in principle. With your framework assemblies, it makes no sense. I recommend that when you start writing common helper classes, core interfaces etc. in your core assemblies, and make the default namespace of those projects the highest that it can be e.g. Company.App. Then make folders in the project for each area that your framework goes across. The name of your assemblies do not need to follow the assembly-follows-namespace standard.
Framework classes should be carefully distributed across the entire namespace of your system. All your framework classes should not get bundled up into one uber-namespace, or bundled underneath .Framework. Framework types relating to Services should live in the same namespace that your team write their services in. Types relating to UI should live in the same namespace that your team write their views in.