In early 2015, Sitecore released the Habitat project. This project is an example of an implementation using the Helix framework. One of the major complaints about Habitat was the large number of projects. Managing and compiling the Habitat solution can, in some cases, be somewhat difficult. I feel one of the reasons behind the large number of projects is to help enforce the Module inheritance rules specified in Helix. By separating each module into its own project, cross module dependencies become more obvious.
If a better way can be found to track down violations of the Helix design principals, some of the components in a typical Helix implementation can be combined, resulting in fewer projects and faster build times.
The Helix documentation provides a very good explanation of the rules, and reasons for the rules, governing Helix implementations. I’m not going to reproduce that here. My quick summary of Helix rules for module dependencies is as follows:
- There is a strict reference hierarchy of module categories. Projects -> Features -> Foundations.
- Project modules cannot reference other projects, but can reference any Features and Foundations.
- Feature modules cannot reference any Project modules or other Feature modules. They can reference Foundations
- Foundations can only reference other Foundations.
- There is a strict namespace naming convention of [ProjectNamspaces].(Project|Feature|Foundation).[ModuleName].[SubNamspaces].
Even if modules are separated into their own projects, it is still relatively easy for rogue developers to add a reference to another module that breaks the above rules. Catching this relies on having a process that makes note of new references and makes sure they don’t break the rules. This can be error prone.
Having the Helix rules checked every time the project is compiled would be ideal. Fortunately, this is exactly what FxCop was designed to do. By adding 5 simple rules, FxCop can make sure the Helix design principals are adhered to.
By following the naming convention for Helix namespaces, FxCop rules can be constructed to make sure modules aren’t referencing components in violation of the Helix rules listed above.
Here are the rules:
- ScHlx001 – Validate Helix Projects do not access other Projects
- ScHlx002 – Validate Helix Feature do not access other Features
- ScHlx004 – Validate Helix Features do not access Projects
- ScHlx005 – Validate Helix Foundations do no access Projects
- ScHlx006 – Validate Helix Foundations do not access Features
The astute reader will notice ScHlx003 is missing from the list. This rule checks to make sure Foundations do not access other Foundations. This isn’t forbidden by the Helix documentation, but was quite easy to implement, so it was included in case developers want to track their cross Foundation references.
Installing the FxCop Rules
The FxCop rules have only been tested in VS2015. Other versions of Visual Studio are not supported at this time. The first step in installing the rules is to add the HedgehogDevelopment.FxCop.Helix NuGet package to each web project in the solution (sorry, Habitat developers). You can find this package on the NuGet.Org repository.
You also need to move the FxCop assembly into a Visual Studio. Please copy the assembly [SolutionDir]\packages\HedgehogDevelopment.FxCop.Helix.X.x.x.x\build\FxCop\Rules\HedgehogDevelopment.FxCop.Helix.dll to the folder C:\Program Files (x86)\Microsoft Visual Studio 14.0\Team Tools\Static Analysis Tools\FxCop\Rules.
You may need to restart Visual Studio after doing this. Copying this assembly installs the rules for FxCop and gives Visual Studio access to them.
To enable the rules in your project, open the project properties and go to the Code Analysis tab.
Next, create a custom rule set and view it in the rule set editor.
Select Group by: Category in the drop-down at the top left of the ruleset editor. You should see a category called “Helix”. Please open this and select the rules you are interested in.
Save the ruleset and then right-click on the solution and select “Run code analysis on the solution”.
This should generate errors that look like:
One of the main reasons these FxCop rules were created was to allow us to reduce the number of projects in the Habitat implementation while sticking closely to the Helix architecture. We feel these FxCop rules enables developers to easily ensure their projects are following the “High Cohesion and Low Coupling” design pattern of Helix.