NDepend Default Rules for .NET
Every new NDepend project comes with 235 rules, 22 quality gates and 136 code queries and trend metrics, checked on your C# and .NET code in Visual Studio, in CI and in reports. Each one is a few lines of CQLinq (C# LINQ over the code model) that you can read and adapt. Each page below gives the description, how to fix the issues, and the full CQLinq source. Prefer to browse and search interactively? Use the Rules Explorer.
- Quality Gates
- Hot Spots
- Code Smells
- Code Smells Regression
- Object Oriented Design
- Design
- Architecture
- API Breaking Changes
- Code Coverage
- Dead Code
- Security
- Visibility
- Immutability
- Naming Conventions
- Source Files Organization
- .NET Framework Usage
- API Usage
- Defining JustMyCode
- Trend Metrics
- Code Diff Summary
- Statistics
- Samples of Custom rules
Quality Gates (19)
- Quality Gates Evolution
- Percentage Coverage
- Percentage Coverage on New Code
- Percentage Coverage on Refactored Code
- Percentage Coverage (JustMyCode)
- Percentage Coverage on New Code (JustMyCode)
- Percentage Coverage on Refactored Code (JustMyCode)
- Blocker Issues
- Critical Issues
- New Blocker / Critical / High Issues
- Critical Rules Violated
- Treat Compiler Warnings as Error
- Percentage Debt
- Debt
- New Debt since Baseline
- Debt Rating per Namespace
- Annual Interest
- New Annual Interest since Baseline
- Unnecessary NDepend SuppressMessageAttribute Usage
Hot Spots (7)
- Types Hot Spots
- Types to Fix Priority
- Issues to Fix Priority
- Debt and Issues per Rule
- New Debt and Issues per Rule
- Debt and Issues per Code Element
- New Debt and Issues per Code Element
Code Smells (10)
- Avoid types too big ND1000
- Avoid types with too many methods ND1001
- Avoid types with too many fields ND1002
- Avoid methods too big, too complex ND1003
- Avoid methods with too many parameters ND1004
- Avoid methods with too many overloads ND1005
- Avoid methods potentially poorly commented ND1006
- Avoid types with poor cohesion ND1007
- Avoid methods with too many local variables ND1008
- Avoid unmaintainable code ND1009
Code Smells Regression (9)
- From now, all types added should respect basic quality principles ND1100
- From now, all types added should be 100% covered by tests ND1101
- From now, all methods added should respect basic quality principles ND1102
- Avoid decreasing code coverage by tests of types ND1103
- Avoid making complex methods even more complex ND1104
- Avoid making large methods even larger ND1105
- Avoid adding methods to a type that already had many methods ND1106
- Avoid adding instance fields to a type that already had many instance fields ND1107
- Avoid transforming an immutable type into a mutable one ND1108
Object Oriented Design (14)
- Avoid interfaces too big ND1200
- Base class should not use derivatives ND1201
- Class shouldn't be too deep in inheritance tree ND1202
- Class with no descendant should be sealed if possible ND1203
- Overrides of Method() should call base.Method() ND1204
- Do not hide base class methods ND1205
- A stateless class or structure might be turned into a static type ND1206
- Non-static classes should be instantiated or turned to static ND1207
- Methods should be declared static if possible ND1208
- Constructor should not call a virtual method ND1209
- Avoid the Singleton pattern ND1210
- Don't assign static fields from instance methods ND1211
- Avoid empty interfaces ND1212
- Avoid types initialization cycles ND1213
Design (16)
- Avoid custom delegates ND1300
- Types with disposable instance fields must be disposable ND1301
- Disposable types with unmanaged resources should declare finalizer ND1302
- Methods that create disposable object(s) and that don't call Dispose() ND1303
- Disposable Types Must Unsubscribe Events ND1315
- Classes that are candidate to be turned into structures ND1304
- Avoid namespaces with few types ND1305
- Nested types should not be visible ND1306
- Declare types in namespaces ND1307
- Empty static constructor can be discarded ND1308
- Instances size shouldn't be too big ND1309
- Attribute classes should be sealed ND1310
- Don't use obsolete types, methods or fields ND1311
- Do implement methods that throw NotImplementedException ND1312
- Override equals and operator equals on value types ND1313
- Boxing/unboxing should be avoided ND1314
Architecture (13)
- Avoid namespaces mutually dependent ND1400
- Avoid namespaces dependency cycles ND1401
- Avoid partitioning the code base through many small library Assemblies ND1402
- Enforcing Clean Architecture ND1412
- UI layer shouldn't use directly DB types ND1403
- UI layer shouldn't use directly DAL layer ND1404
- Assemblies with poor cohesion (RelationalCohesion) ND1405
- Namespaces with poor cohesion (RelationalCohesion) ND1406
- Assemblies that don't satisfy the Abstractness/Instability principle ND1407
- Avoid excessive class coupling ND1410
- Higher cohesion - lower coupling ND1408
- Avoid mutually-dependent types ND1409
- Example of custom rule to check for dependency ND9900
API Breaking Changes (9)
- API Breaking Changes: Types ND1500
- API Breaking Changes: Methods ND1501
- API Breaking Changes: Fields ND1502
- API Breaking Changes: Interfaces and Abstract Classes ND1503
- Broken serializable types ND1504
- Avoid changing enumerations Flags status ND1505
- API: New publicly visible types
- API: New publicly visible methods
- API: New publicly visible fields
Code Coverage (15)
- Code should be tested ND1600
- New Types and Methods should be tested ND1601
- Methods refactored should be tested ND1602
- Assemblies and Namespaces should be tested ND1603
- Types almost 100% tested should be 100% tested ND1604
- Namespaces almost 100% tested should be 100% tested ND1605
- Types that used to be 100% covered by tests should still be 100% covered ND1606
- Types tagged with FullCoveredAttribute should be 100% covered ND1607
- Types 100% covered should be tagged with FullCoveredAttribute ND1608
- Methods should have a low C.R.A.P score ND1609
- Complex Methods should be 100% tested ND1610
- Test methods should assert something ND1611
- Test Methods
- Methods directly called by test Methods
- Methods directly and indirectly called by test Methods
Dead Code (5)
- Potentially Dead Types ND1700
- Potentially Dead Methods ND1701
- Potentially Dead Fields ND1702
- Wrong usage of IsNotDeadCodeAttribute ND1703
- Code used only by tests ND1704
Security (39)
- Software Composition Analysis (SCA) ND3120
- Transitive Software Composition Analysis (SCA) ND3121
- Don't hard-code secrets in constants ND3114
- Review credentials built from hard-coded values ND3115
- Don't use insecure deserializers ND3110
- Don't use weak hash algorithms (MD5, SHA1) ND3109
- Don't use DES/3DES/RC2 weak cipher algorithms ND3102
- Don't use weak password-based key derivation ND3123
- Don't use the ECB encryption mode ND3132
- Don't disable certificate validation ND3103
- Don't hard-code TLS/SSL protocol versions ND3122
- Review commands vulnerable to SQL injection ND3107
- Review data adapters vulnerable to SQL injection ND3108
- Review raw SQL built from composed strings ND3128
- Review LDAP filters composed from strings ND3137
- Don't enable external XML entity resolution (XXE) ND3111
- Review processes started with a composed arguments string ND3124
- Review web endpoints building file paths from their parameters ND3129
- Review custom archive extraction (Zip Slip) ND3135
- Review assemblies and types loaded from runtime-provided names ND3125
- Review web endpoints without [Authorize] nor [AllowAnonymous] ND3118
- Review state-changing endpoints opened to anonymous callers ND3130
- Review state-changing MVC actions without anti-forgery validation ND3119
- Review HTML-encoding bypasses ND3133
- Review explicitly disabled request validation ND3134
- Review redirects to a URL that is not validated as local ND3126
- Review request-influenced outbound HTTP calls (SSRF) ND3136
- Review insecure ASP.NET Core CORS policies and unguarded developer exception page ND3116
- Review cookies created without HttpOnly and Secure flags ND3117
- Review regular expressions without a match timeout (ReDoS) ND3112
- Review secrets compared with non-constant-time equality ND3113
- Review secrets passed to logging methods ND3127
- Review security operations that log nothing ND3131
- Don't use System.Random for security purposes ND3101
- Don't use CoSetProxyBlanket and CoInitializeSecurity ND3100
- Review publicly visible event handlers ND3104
- Pointers should not be publicly visible ND3105
- Seal methods that satisfy non-public interfaces ND3106
- Restrict sensitive APIs to reviewed components ND3138
Visibility (12)
- Methods that could have a lower visibility ND1800
- Types that could have a lower visibility ND1801
- Fields that could have a lower visibility ND1802
- Types that could be declared as private, nested in a parent type ND1803
- Avoid publicly visible constant fields ND1804
- Fields should be declared as private or protected ND1805
- Constructors of abstract classes should be declared as protected or private ND1806
- Avoid public methods not publicly visible ND1807
- Event handler methods should be declared as private or protected ND1808
- Wrong usage of CannotDecreaseVisibilityAttribute ND1809
- Exception classes should be declared as public ND1810
- Methods that should be declared as 'public' in C#, 'Public' in VB.NET
Immutability (15)
- Fields should be marked as ReadOnly when possible ND1900
- Avoid non-readonly static fields ND1901
- Avoid static fields with a mutable field type ND1902
- Structures should be immutable ND1903
- Immutable struct should be declared as readonly ND1914
- Property Getters should be pure ND1904
- A field must not be assigned from outside its parent hierarchy types ND1905
- Don't assign a field from many methods ND1906
- Do not declare read only fields with mutable reference types ND1907
- Public read only array fields can be modified ND1908
- Types tagged with ImmutableAttribute must be immutable ND1909
- Types immutable should be tagged with ImmutableAttribute ND1910
- Methods tagged with PureAttribute must be pure ND1911
- Pure methods should be tagged with PureAttribute ND1912
- Record should be immutable ND1913
Naming Conventions (23)
- Instance fields naming convention ND2000
- Static fields naming convention ND2001
- Interface name should begin with a 'I' ND2002
- Abstract base class should be suffixed with 'Base' ND2003
- Exception class name should be suffixed with 'Exception' ND2004
- Attribute class name should be suffixed with 'Attribute' ND2005
- Types name should begin with an Upper character ND2006
- Methods name should begin with an Upper character ND2007
- Do not name enum values 'Reserved' ND2008
- Avoid types with name too long ND2009
- Avoid methods with name too long ND2010
- Avoid fields with name too long ND2011
- Avoid having different types with same name ND2012
- Avoid prefixing type name with parent namespace name ND2013
- Avoid naming types and namespaces with the same identifier ND2014
- Don't call your method Dispose ND2015
- Methods prefixed with 'Try' should return a boolean ND2016
- Properties and fields that represent a collection of items should be named Items. ND2017
- DDD ubiquitous language check ND2018
- Avoid fields with same name in class hierarchy ND2019
- Avoid various capitalizations for method name ND2020
- Controller class name should be suffixed with 'Controller' ND2021
- Nested class members should not mask outer class' static members ND2022
Source Files Organization (6)
- Avoid referencing source file out of the project directory ND2100
- Avoid duplicating a type definition across assemblies ND2101
- Avoid defining multiple types in a source file ND2102
- Namespace name should correspond to file location ND2103
- Types with source files stored in the same directory, should be declared in the same namespace ND2104
- Types declared in the same namespace, should have their source files stored in the same directory ND2105
.NET Framework Usage
System (12)
- Mark ISerializable types with SerializableAttribute ND2200
- Mark assemblies with CLSCompliant (deprecated) ND2201
- Mark assemblies with ComVisible (deprecated) ND2202
- Mark attributes with AttributeUsageAttribute ND2203
- Remove calls to GC.Collect() ND2204
- Don't call GC.Collect() without calling GC.WaitForPendingFinalizers() ND2205
- Enum Storage should be Int32 ND2206
- Do not raise too general exception types ND2207
- Do not raise reserved exception types ND2208
- Uri fields or properties should be of type System.Uri ND2209
- Types should not derive from System.ApplicationException ND2210
- Don't Implement ICloneable ND2211
System.Collections (4)
- Collection properties should be read only ND2300
- Don't use .NET 1.x HashTable and ArrayList ND2301
- Caution with List.Contains() ND2302
- Prefer return collection abstraction instead of implementation ND2303
System.Runtime.InteropServices (3)
- P/Invokes should be static and not be publicly visible ND2400
- Move P/Invokes to NativeMethods class ND2401
- NativeMethods class should be static and internal ND2402
System.Threading (6)
- Don't create threads explicitly ND2500
- Don't use dangerous threading methods ND2501
- Monitor TryEnter/Exit must be both called within the same method ND2502
- ReaderWriterLock AcquireLock/ReleaseLock must be both called within the same method ND2503
- Don't tag instance fields with ThreadStaticAttribute ND2504
- Method non-synchronized that read mutable states ND2505
System.Xml (2)
- Method should not return concrete XmlNode ND2600
- Types should not derive from System.Xml.XmlDocument ND2601
System.Globalization (1)
System.Reflection (3)
- Mark assemblies with assembly version ND2800
- Assemblies should have the same version ND2801
- Assemblies Referenced in Multiple Versions ND2802
Microsoft.Contracts (1)
API Usage
Unity (9)
- Classes tagged with InitializeOnLoad should have a static constructor ND3200
- Avoid using non-generic GetComponent ND3201
- Avoid empty Unity message ND3202
- Avoid using Time.fixedDeltaTime with Update ND3203
- Use CreateInstance to create a scriptable object ND3204
- The SerializeField attribute is redundant on public fields ND3205
- InitializeOnLoadMethod should tag only static and parameterless methods ND3206
- Prefer using SetPixels32() over SetPixels() ND3207
- Don't use System.Reflection in performance critical messages ND3208
Defining JustMyCode (7)
- Discard generated Assemblies from JustMyCode ND3000
- Discard generated Namespaces from JustMyCode ND3001
- Discard generated Types from JustMyCode ND3002
- Discard generated and designer Methods from JustMyCode ND3003
- Discard generated Fields from JustMyCode ND3004
- JustMyCode code elements
- NotMyCode code elements
Trend Metrics
Issues (11)
- # New Issues since Baseline
- # Issues Fixed since Baseline
- # Issues Worsened since Baseline
- # Issues with severity Blocker
- # Issues with severity Critical
- # Issues with severity High
- # Issues with severity Medium
- # Issues with severity Low
- # Blocker/Critical/High Issues
- # Issues
- # Suppressed Issues
Rules (3)
Quality Gates (3)
Debt (7)
- Percentage Debt (Metric)
- Debt (Metric)
- New Debt since Baseline (Metric)
- Annual Interest (Metric)
- New Annual Interest since Baseline (Metric)
- Breaking Point
- Breaking Point of Blocker / Critical / High Issues
Code Size (22)
- # Lines of Code
- # Lines of Code (JustMyCode)
- # Lines of Code (NotMyCode)
- # Lines of Code Added since the Baseline
- # Source Files
- # Line Feed
- # IL Instructions
- # IL Instructions (NotMyCode)
- # Lines of Comments
- Percentage of Comments
- # Assemblies
- # Namespaces
- # Types
- # Public Types
- # Classes
- # Abstract Classes
- # Interfaces
- # Structures
- # Methods
- # Abstract Methods
- # Concrete Methods
- # Fields
Maximum and Average (15)
- Max # Lines of Code for Methods (JustMyCode)
- Average # Lines of Code for Methods
- Average # Lines of Code for Methods with at least 3 Lines of Code
- Max # Lines of Code for Types (JustMyCode)
- Average # Lines of Code for Types
- Max Cyclomatic Complexity for Methods
- Average Cyclomatic Complexity for Methods
- Max IL Cyclomatic Complexity for Methods
- Average IL Cyclomatic Complexity for Methods
- Max IL Nesting Depth for Methods
- Average IL Nesting Depth for Methods
- Max # of Methods for Types
- Average # Methods for Types
- Max # of Methods for Interfaces
- Average # Methods for Interfaces
Coverage (12)
- Percentage Code Coverage
- # Lines of Code Covered
- # Lines of Code Not Covered
- # Tests
- # Lines of Code Uncoverable
- # Lines of Code in Types 100% Covered
- # Lines of Code in Methods 100% Covered
- Max C.R.A.P Score
- Average C.R.A.P Score
- Percentage JustMyCode Coverage
- # Lines of JustMyCode Covered
- # Lines of JustMyCode Not Covered
Third-Party Usage (6)
- # Third-Party Assemblies Used
- # Third-Party Namespaces Used
- # Third-Party Types Used
- # Third-Party Methods Used
- # Third-Party Fields Used
- # Third-Party Code Elements Used
Code Diff Summary (25)
- New assemblies
- Assemblies removed
- Assemblies where code was changed
- New namespaces
- Namespaces removed
- Namespaces where code was changed
- New types
- Types removed
- Types where code was changed
- Heuristic to find types moved from one namespace or assembly to another
- Types directly using one or several types changed
- Types indirectly using one or several types changed
- New methods
- Methods removed
- Methods where code was changed
- Methods directly calling one or several methods changed
- Methods indirectly calling one or several methods changed
- New fields
- Fields removed
- Third party types that were not used and that are now used
- Third party types that were used and that are not used anymore
- Third party methods that were not used and that are now used
- Third party methods that were used and that are not used anymore
- Third party fields that were not used and that are now used
- Third party fields that were used and that are not used anymore
Statistics (13)
- Most used types (Rank)
- Most used methods (Rank)
- Most used assemblies (#AssembliesUsingMe)
- Most used namespaces (#NamespacesUsingMe )
- Most used types (#TypesUsingMe )
- Most used methods (#MethodsCallingMe )
- Namespaces that use many other namespaces (#NamespacesUsed )
- Types that use many other types (#TypesUsed )
- Methods that use many other methods (#MethodsCalled )
- High-level to low-level assemblies (Level)
- High-level to low-level namespaces (Level)
- High-level to low-level types (Level)
- High-level to low-level methods (Level)
Samples of Custom rules
Check Architecture (10)
- Check that the assembly Asm1 is not using the assembly Asm2 ND9901
- Check that the namespace N1.N2 is not using the namespace N3.N4.N5 ND9902
- Check that the assembly Asm1 is only using the assemblies Asm2, Asm3 or System.Runtime ND9903
- Check that the namespace N1.N2 is only using the namespaces N3.N4, N5 or System ND9904
- Check that AsmABC is the only assembly that is using System.Collections.Concurrent ND9905
- Check that only 3 assemblies are using System.Collections.Concurrent ND9906
- Check that all methods that call Foo.Fct1() also call Foo.Fct2(Int32) ND9907
- Check that all types that derive from Foo, also implement IFoo ND9908
- Check that all types that has the attribute FooAttribute are declared in the namespace N1.N2* ND9909
- Check that all synchronization objects are only used from the namespaces under MyNamespace.Sync ND9910
Check Coverage on particular Code Elements (4)
- Check that the namespace N1.N2 is 100% covered by tests ND9911
- Check that the assembly Asm is 100% covered by tests ND9912
- Check that the class Namespace.Foo is 100% covered by tests ND9913
- Check that the method Namespace.Foo.Method(Int32) is 100% covered by tests ND9914