Home > View Post

Projects and Namespaces

We currently stick to a couple of strict rules about the naming of projects and assemblies and the use of namespaces.

Our assemblies are usually called something like this: CompanyName.AreaOrSystem.Application.LibraryName

For instance, in the code running this blog that might be TheJoyOfCode.WebSite.Blog.Logic for the library that contains most of our 'business' logic or TheJoyOfCode.Common.Essentials for our 'essential' utility* library. If you think that looks a lot like a namespace then you'd be right.

Project properties showing assembly name and default namespace

To keep things nice and consistent, we also use this assembly name as the default namespace and the Project Name. All classes within that project will belong to that namespace or a child of that namespace. The final rule is that an assembly cannot extend the namespace of another assembly (so you can't have TheJoyOfCode.Common.Essentials.dll and TheJoyOfCode.Common.Essentials.AnotherThingHere.dll, likewise you couldn't later add a TheJoyOfCode.Common.dll).

Solution tree showing project naming conventions

At first this may look a little odd, but once you get used to it there really is no going back. It encourages us to think carefully about how we separate our applications and what naming we should use. It makes it easy to know in which project we could find a particular type that threw an exception, just by looking at the callstack. Furthermore, it can even help avoid bugs!

I once ran into a nasty issue with a web service where I accidentally had two classes with the same name and namespace in different projects. One of these classes was my actual WebService class:

namespace TheJoyOfCode.Example.Service
{
    [WebService]
    public class ServiceClass
    {
        [WebMethod]
        public void DoSomething()
        {
            /*...*/
        }
    }
}

and in another assembly (which was referenced by the above Web Service)

namespace TheJoyOfCode.Example.Service
{
    public class ServiceClass
    {
        /* ... */
    }
}

I accept this is pretty silly but it was a mistake and it happens to the best of us. The result was that sometimes my Web Service worked fine and at other times all the methods disappeared completely (aren't they the best kind of bugs?)!

At first, I was shocked that this wasn't picked up by the compiler but each project (assembly) is compiled separately and has no knowledge of the other projects in the solution. The Web Service class is referenced only by a string in the .asmx file so the CLR just chooses the first one it fancies with that name:

<%@ WebService Class="TheJoyOfCode.Example.Service.Serviceclass" %>

This issue actually appeared in MSDN Magazine's Q&A section: http://msdn.microsoft.com/msdnmag/issues/05/05/WebQA/ (if you look closely you'll see I even get a credit at the bottom :)

If the naming conventions I outlined above had been in place at the time, we'd never have had this issue.

How do you structure your projects?

*On a tangent - I personally hate 'dumping ground' utility libraries that end up chock full of little methods added by every project. We called our's 'Essentials' to indicate that only stuff that is essential to all applications should go in there (such as Configuration helpers, DataAccess helpers etc).

Tags: .NET

 
Josh Post By Josh Twist
5:29 AM
29 Mar 2006

» Next Post: Validator Module on Computerzen.com
« Previous Post: Tuning the ThreadPool

Comments are closed for this post.

© 2005 - 2017 Josh Twist - All Rights Reserved.