This project has moved. For the latest updates, please go here.
This project has been moved to GitHub.
For the latest documentation please follow this link:

Dependency Control

Why care about code dependencies?

"Poor dependency management leads to code that is hard to change, fragile, and non-reusable" as Uncle Bob said.
Dependency control tools help you enforce some sort of organizing scheme so your code base doesn't degrade with time into a tangled mess.
If you want to learn more about dependency management I highly recommend Uncle Bob's articles, books and training videos.

How to control code dependencies?

Dependency control tools let you describe your intention about allowed and disallowed dependencies and warn you about dependency violations.
They can work at different levels and on different forms of input:
  • at the physical level (projects, libraries, assemblies), or the logical level (namespaces and types),
  • on the source code or on the compiled (binary or intermediary) form.
This tool checks dependencies at the namespace level, in the source code.
It also supports some fine-tuning at the type level (see details below).

So what is a namespace dependency?

Namespace 'A' depends on namespace 'B' if any type declared in namespace 'A' uses any type declared in namespace 'B'. “Using” a type means any occurrence of that type, eg. as the type of a member, a method parameter, a local variable, a type argument, anything.

Why namespace and not type dependencies?

In my experience enforcing dependency rules at the type level results in a verbose and brittle dependency description.
Namespaces are a better target for the dependency rules because they give you a level of abstraction above types and also a hierarchical organization that can simplify dependency rules by allowing dependencies to be specified not only between logical packages but also between trees/subtrees of packages.

Why does this tool support some type level dependency control?

There's a scenario when you as the designer of a system's structure use some third party or legacy stuff whose structure you don't control but still want to limit your system's dependency on it. So when depending on a namespace you can define a subset of its types as the visible part or the "surface" of that namespace. All other types in that namespace will be illegal to depend upon.

What is the recommended approach?

  • Define the high level structure of your system as a hierarchy of logical modules/packages.
    • Better upfront to avoid a lot of refactoring later.
    • NsDepCop won't help you with this. Use a modeling tool or just pen and paper.
  • Implement the logical modules/packages with C# namespaces.
    • Maintain a 1-to-1 correspondence between logical units and namespaces.
  • Describe the allowed namespace dependencies in NsDepCop config files.
    • 1 file per C# project.
  • Run NsDepCop as part of the build process and fix illegal dependencies early.
    • Sometimes it will require some rethinking/redesign in the architecture.

Last edited Mar 26 at 2:15 PM by vizu, version 21


No comments yet.