Sitecore namespace issues

Since I ran into this silly issue a couple of times I decided to dig into it a little bit and write a post about it. As developers we like to structure our solutions and projects by applying consistent naming conventions. Most Sitecore projects use a naming convention like this prefix.Sitecore.description. Usually the prefix is something like a company name or a brand name, and the description is something that describes the project’s role in the solution. There can also be multiple prefixes and descriptions separated by a period. Looking at Habitat an example of description could be Feature.Accounts.

A popular approach is to keep project names, assembly names, folder structure and namespaces all in sync for clarity. If you go with this approach you will end up with a namespace like MyBrand.Sitecore.Features.Accounts. This is where things can get a little messy because “Sitecore” is in the namespace and this can conflict with references to Sitecore DLL’s. Consider below piece of code:

namespace MyBrand.Sitecore.Features.Accounts
{
    using Sitecore;

    public class Helper
    {
        public string ReturnCurrentItemName()
        {
            var item = Sitecore.Context.Item;

            return item.Name;
        }
    }
}

This code will create below compile error:

Error CS0234 The type or namespace name ‘Context’ does not exist in the namespace ‘MyBrand.Sitecore’ (are you missing an assembly reference?)

Problem

The problem here is how namespace resolution works for nested namespaces, more details can be found in the C# language specification here. As the compile error suggests it is looking for the Context object in our class instead of in Sitecore in the root scope. The good news is that there are at least 3 different ways to solve this:

1. Avoid using anything before “Sitecore” in namespace

The same code will compile just fine when “Sitecore” is the first part of the namespace, see line 1. This is the easiest solution if changing the namespace is not a problem.

namespace Sitecore.Features.Accounts
{
    using Sitecore;

    public class Helper
    {
        public string ReturnCurrentItemName()
        {
            var item = Sitecore.Context.Item;

            return item.Name;
        }
    }
}

2. Use namespace alias

This is my least favorite way to solve this but it also seems to be the most common solution. The Sitecore namespace from the Sitecore DLL can be declared as an alias and then used to reference:

using RealSitecore = Sitecore;

namespace MyBrand.Sitecore.Features.Accounts
{
    public class Helper
    {
        public string ReturnCurrentItemName()
        {
            var item = RealSitecore.Context.Item;

            return item.Name;
        }
    }
}

3. Use global namespace alias

Instead of making up a random name for Sitecore as in the last solution, it feels a lot cleaner to use the global namespace alias to tell the compiler to look in the global namespace instead:

namespace MyBrand.Sitecore.Features.Accounts
{
    using Sitecore;

    public class Helper
    {
        public string ReturnCurrentItemName()
        {
            var item = global::Sitecore.Context.Item;

            return item.Name;
        }
    }
}

Summary

As long as there is no problem changing the namespace to start with “Sitecore” then option 1 is the best choice. If for whatever reason that is not an option then go with using the global namespace alias as described in option 3.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s