Code Rule and Code Query
Hundreds of default code rules to check against best practices. Support for Code Query over C# LINQ (CQLinq) to easily customize rules and query code.
Most companies have large systems that work together, often in mysterious ways. NDepend's in-depth reporting and toolset can help your company enforce its own coding standards and maintain complex projects.
Hundreds of default code rules to check against best practices. Support for Code Query over C# LINQ (CQLinq) to easily customize rules and query code.
Explore how the code is actually structured and shed light on architectural flaws thanks to the most powerful code dependency graph and dependency matrix available in the tool industry.
For each issue, the cost to fix and the severity are estimated through smart and customizable C# formulas. Thus estimations proposed are realistic.
A unique approach to continuously keep the technical debt under control and reimburse it with time.
Integrate NDepend analysis into your CI / CD pipeline and obtain interactive and detailed web reports to explore progression and prevent code quality degradation.
Fail the build pipeline upon customizable PASS / WARN / FAIL code quality and security criteria.
Gain a 360 view of your .NET code quality by importing your preferred Roslyn Analyzers' issues and ReSharper Code Inspections' issues into the NDepend web report and UI.
NDepend allows your team to accurately gauge the overall health of your application, no matter how complex it is.
Lines of Code, Cyclomatic Complexity, Coupling, Nesting Depth, Rank, NDepend supports them all (and much more).
Get Trend Charts about pretty much any code metrics to master the evolution of your application.
Import test coverage data, and make the most of it in the NDepend feature-rich context.
NDepend's reporting and analysis helps architects and developers to communicate and reduce confusion.
Spot too complex code at a glance thanks to unique diagramming capabilities.
Compare two versions of a code base and its issues set, and browse diff and changes in any way you can think of.
Be warned of potential build process problems before they end up causing friction and pain.
By mapping out the structure of the project, it is much easier to see how components and dependencies are connected.
Get rid of dependency cycles between components to achieve higher code maintainability.
NDepend helps maintaining clean side-effects free code to write highly maintainable products.
Integrate with Visual Studio, Azure DevOps, GitHub and any other CI/CD pipeline, super fast and lightweight analysis, NDepend is conceived for real-world programmers.
Write your own static analyzer based on NDepend.API, or tweak existing open-sources Power Tools.
Explore the issues-set in a few clicks and focus your effort on what is urgent and important.
NDepend lets query the code base over LINQ queries thanks to CQLinq.
For example the following CQLinq query matches all public methods that have more than 30 lines of code:
from m in Application.Methods
where m.NbLinesOfCode > 30 && m.IsPublic
select m
Around 200 default queries and rules are provided when you create a new NDepend project.
They are easy to read and easy to adapt to your need.
Writing CQLinq queries and constraints is straightforward both because it is C# LINQ syntax and because NDepend provides a CQLinq editor which supports:
Also, once the query is compiled, it gets executed immediately and its result is well displayed and is easy to browse:
Powerful and elaborated queries and rules can be written with CQLinq, like the following one for example:
// <Name>UI layer shouldn't use directly DB types</Name>
warnif count > 0
// UI layer is made of types using a UI framework
let uiTypes = Application.Types.UsingAny(Assemblies.WithNameIn(
"PresentationFramework", "System.Windows", "System.Windows.Forms", "System.Web"))
// You can easily customize this part to define what are DB types.
let dbTypes = ThirdParty.Assemblies.WithNameIn("System.Data", "EntityFramework", "NHibernate").ChildTypes()
.Except(ThirdParty.Types.WithNameIn("DataSet", "DataTable", "DataRow"))
from uiType in uiTypes.UsingAny(dbTypes)
let dbTypesUsed = dbTypes.Intersect(uiType.TypesUsed)
let dbTypesAndMembersUsed = dbTypesUsed.Union(dbTypesUsed.ChildMembers().UsedBy(uiType))
// Per defaut this rule estimates a technical debt
// proportional to the coupling between the UI and DB types.
let couplingPerUIType = 2 +
uiType.Methods.UsingAny(dbTypesUsed).Count() +
dbTypesAndMembersUsed.Count()
select new {
uiType,
dbTypesAndMembersUsed,
Debt = (4 * couplingPerUIType).ToMinutes().ToDebt(),
Severity = Severity.Major
}
//<Description>
// This rule is more a *sample rule to adapt to your need*,
// than a rigid rule you should abide by. It shows how to
// define code layers in a rule and how to be warned about
// layers dependencies violations.
//
// This rule first defines the UI layer and the DB framework
// layer. Second it checks if any UI layer type is using
// directly any DB framework layer type.
//
// • The **DB framework layer** is defined as the set of *third-party*
// types in the framework *ADO.NET*, *EntityFramework*,
// *NHibernate* types, that the application is consuming.
// It is easy to append and suppress any DB framework.
//
// • The UI layer (**User Interface Layer**) is defined as the
// set of types that use *WPF*, *Windows Form*, *ASP.NET*.
//
// *UI using directly DB frameworks* is generally considered
// as *poor design* because DB frameworks accesses should be
// a concept hidden to UI, encapsulated into a **dedicated
// Data Access Layer (DAL)**.
//
// Notice that per defaut this rule estimates a technical debt
// proportional to the coupling between the UI and DB types.
//</Description>
//<HowToFix>
// This rule lists precisely which UI type uses which
// DB framework type. Instead of fixing matches one by one,
// first imagine how DB framework accesses could be
// encapsulated into a dedicated layer.
//</HowToFix>
Note how a C# formula can be used to estimate the technical-debt and issues severity. Also note that a description and how-to-fix guideline can be provided. This text will be rendered nicely for non-developers.
Short CQLinq queries can be written (or even generated) to get some immediate answers to questions about a code base:
Is the code layered correctly?
from n in Namespaces where n.Level == null select n
Which methods have been refactored since the last release and are not thoroughly covered by tests?
from m in Application.Methods where
m.CodeWasChanged() && m.PercentageCoverage < 100
select new { m, m.PercentageCoverage }
Which classes implement a particular interface?
from t in Types
where t.IsClass && t.Implement("System.IDisposable")
select t
Which methods create objects of a particular class?
from m in Methods where m.CreateA ("MyNamespace.MyClass") select m
Which methods assign a particular field?
from m in Methods
where m.AssignField("MyNamespace.MyClass.m_Field")
select m
What are the 10 most complex methods?
(from m in Methods
orderby m.CyclomaticComplexity
select new { m, m.CyclomaticComplexity }).Take(10)
Which method could have a more restricted visibility?
from m in Application.Methods
where m.Visibility != m.OptimalVisibility
select new { m,
m.Visibility ,
CouldBeDeclared = m.OptimalVisibility,
m.MethodsCallingMe }
Which complex method is not enough commented?
from m in Application.Methods
where m.CyclomaticComplexity > 15 && m.PercentageComment < 10
select new { m, m.CyclomaticComplexity, m.PercentageComment }
CQLinq can also be used to write Quality Gates. A Quality Gate is a criterion that must be verified before going to production
A dozen of default Quality Gates checks criteria such as overall Code Coverage by tests or extra Technical Debt since baseline.
This Quality Gate ensures a minimum percentage coverage by tests on new methods introduced since baseline.
// <QualityGate Name="Percentage Coverage on New Code" Unit="%" />
failif value < 70%
warnif value < 80%
let newMethods = Application.Methods.Where(m => m.WasAdded() && m.NbLinesOfCode > 0)
let locCovered = newMethods.Sum(m => m.NbLinesOfCodeCovered)
let loc = newMethods.Sum(m => m.NbLinesOfCode)
select 100d * locCovered / loc
This Quality Gate ensures a maximum of Technical Debt ratio on the code base.
// <QualityGate Name="Percentage Debt" Unit="%" />
failif value > 30%
warnif value > 20%
let timeToDev = codeBase.EffortToDevelop()
let debt = Issues.Sum(i => i.Debt)
select 100d * debt.ToManDay() / timeToDev.ToManDay()
You can also be warned automatically when a CQLinq query returns a certain result. Such a CQLinq code query is actually a code rule such as:
Static fields should not be named m_XXX (Custom naming conventions):
warnif count > 0
from f in Fields where f.NameLike (@"^m_") && f.IsStatic
select f
Methods out of MyAssembly and MyAssembly2 should not have more than 30 lines of code:
warnif count > 0
from m in Application.Assemblies.WithNameNotIn("MyAssembly1", "MyAssembly2").ChildMethods()
where m.NbLinesOfCode > 30
select new { m, m.NbLinesOfCode }
Public methods should not be removed to avoid API breaking changes:
warnif count > 0
from m in codeBase.OlderVersion().Application.Methods
where m.IsPublic && m.WasRemoved()
select m
Types tagged with the attribute MyNamespace.FullCoveredAttribute must be thoroughly covered by tests:
warnif count > 0
from t in Application.Types
where t.HasAttribute ("NDepend.Attributes.FullCoveredAttribute") &&
t.PercentageCoverage < 100
select new { t, t.PercentageCoverage }
Related Documentation:
Default Rules and Queries
CQLinq Syntax
CQLinq Features
CQLinq Performance
CQL to CQLinq Conversion
Declare CQLinq rules in C# or VB.NET source code