Over time, code starts to “smell bad” or “rot”. It evolves in ways that it wasn’t originally intended to evolve, and little hacks are sometimes made. VS 2010 fights this software atrophy via automation and integration with the overall application lifecycle, which will help you maintain control of your code.
One powerful tool at your disposal is layer diagrams. Layer diagrams allow you to draw your system’s architecture as it should be, map your code to it, and validate that your architectural design and your implementation do not deviate. For example, if you have a standard 3-tier architecture, you could create a layer diagram with 3 boxes: the presentation layer, the business layer, and the data layer. Arrows between the boxes indicate that it’s okay to take a dependency on the node that you’re pointing to. So you would probably draw an arrow from the presentation layer to the business layer and another arrow from the business layer to the data layer. Now, the cool part is that you can map your code to this diagram, and then validate whether this architecture is being followed. You can even set up the build to break if someone writes code in the presentation layer that inadvertently accesses the data layer directly instead of going through the business layer.
To create a new layer diagram, click on the “Architecture” menu item and select “New Diagram”. A dialog box will come up (see below); select “Layer Diagram”. (Full reference on creating layer diagrams is here).
Here is an example of a layer diagram. This diagram can be found in the code sample attached at the end of this post (it’s the PetShop.layerdiagram file under the PetShopModels project).
In this example diagram, we’ve modeled what our architecture should look like. Now, we need to map our code to the diagram. Drag and drop projects from the Solution Explorer or namespaces/classes from the Architecture Explorer onto the appropriate block on the diagram to map your code to the diagram. The number of items that are mapped to each block in the diagram will be displayed in the upper right-hand corner of the block. To view the mapped items, open the Layer Explorer (click on the “Architecture” menu item, select “Windows” and then “Layer Explorer”). For example, you can see from the diagram above that the Business block has 2 items mapped to it. When I open the Layer Explorer and select the Business block in the diagram, I see what those 2 items are; anything in the namespaces “PetShop.BLL” or “PetShop.OrderProcessor” is part of my business layer:
Now, I want to validate that my code meets the requirements of the architecture specified by my layer diagram. To do this, right-click on the layer diagram and select “Validate Architecture”. This analyzes whether your code conforms to the diagram. Note that it’s performing a static analysis, so if there is something that you are doing illegally at runtime, the tool won’t catch this.
If errors exist, they will be displayed in the Error List window in Visual Studio. In the example code, there are two errors:
There are several solutions to deal with errors, which can be easily applied by right-clicking the error:
The final piece of this is to use custom MSBuild tasks to integrate this validation process into your build. Integrating this architectural validation into your build makes it a regular part of your development process, rather than an extra task that you have to do manually.
To do this, open your build definition file from the Team Explorer window. Click on the “Process” option in the left-hand sidebar. Expand “Advanced”. For the “MSBuild Arguments” parameter, enter the value “/p:ValidateArchitecture=true”.
This MSBuild argument will be passed to all projects. However, projects will ignore it if they don’t recognize it, so it will be used only by modeling projects. (Layer diagrams always live inside modeling projects.) Now, it will validate the architecture on every build and cause a build break if validation errors are found.
In summary, layer diagrams allow you to define your ideal architecture, map your code assets to the architecture, and then validate that your implementation matches your architectural design. In tomorrow’s post, I’ll discuss how to better understand the problem domain for your system using UML tools.