Assemblies with poor cohesion (RelationalCohesion)
Warns about assemblies with a wrong Relational Cohesion: the number of relationships between the assembly's types divided by the number of types (average types used per type). Classes inside an assembly should be strongly related, so cohesion should be high. Assemblies with fewer than 20 types are ignored.
How to fix
Matches reveal either specific coding constraints (like generated code) or design issues; in the latter case plan refactoring to increase overall design and maintainability.
Severity is Low: Relational Cohesion informs about code structure but is not actionable. Fixing actionable Architecture and Code Smells issues will necessarily increase the scores.
Severity is Low: Relational Cohesion informs about code structure but is not actionable. Fixing actionable Architecture and Code Smells issues will necessarily increase the scores.
CQLinq source
This rule is written in CQLinq, C# LINQ over the NDepend code model. It ships with every new NDepend project: you can read it, adapt it, or use it as a starting point for your own custom rules.
// <Name>Assemblies with poor cohesion (RelationalCohesion)</Name>
// <Id>ND1405:AssembliesWithPoorRelationalCohesion</Id>
warnif count > 0 from a in Application.Assemblies
// Build the types list on which we want to check cohesion
// This is the assembly 'a' type, minus enumeration
// and types generated by the compiler.
let types = a.ChildTypes.Where(
t => !t.IsGeneratedByCompiler &&
!t.IsEnumeration &&
JustMyCode.Contains(t))
// Absolutly need ToHashet() to have fast Intersect() calls below.
.ToHashSetEx()
// Relational Cohesion metrics is relevant only if there are enough types
where types.LongCount()> 20
// R is the total number of relationship between types of the assemblies.
let R = types.Sum(t => t.TypesUsed.Intersect(types).Count())
// Relational Cohesion formula
let relationalCohesion = (double)R / types.Count
where relationalCohesion < 0.8
select new {
a,
a.ChildTypes,
relationalCohesion,
a.RelationalCohesion,
Debt = 10.ToMinutes().ToDebt(),
Severity = Severity.Low
}
//<Expl>
// The *{0}* has a *Relational Cohesion* value of {2}.
// This suggests that the types within this assembly are loosely coupled,
// potentially signaling an architectural concern.
//</Expl>
//<Desc>
// Warns about assemblies with a wrong *Relational Cohesion*: the number of
// relationships between the assembly's types divided by the number of types
// (average types used per type). Classes inside an assembly should be
// strongly related, so cohesion should be high. Assemblies with fewer than
// 20 types are ignored.
//</Desc>
//<HowToFix>
// Matches reveal either specific coding constraints (like generated code) or
// design issues; in the latter case plan refactoring to increase overall
// design and maintainability.
//
// Severity is **Low**: *Relational Cohesion* informs about code structure
// but **is not actionable**. Fixing actionable **Architecture** and
// **Code Smells** issues will necessarily increase the scores.
//</HowToFix>
Open in the interactive Rules Explorer · All default rules
Architecture: all 13 items
- 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