UI layer shouldn't use directly DAL layer

Rule ND1404 Architecture

A sample rule to adapt to your need showing how to define code layers and be warned about dependency violations. It checks if any UI layer type directly uses any DAL layer type.

- DAL (Data Access Layer): application types using ADO.NET, EntityFramework, NHibernate types (easy to adjust).

- UI layer: types using WPF, Windows Form, ASP.NET.

UI using directly DAL is poor design: DAL accesses should be hidden from UI in an intermediary domain logic. Estimated debt is proportional to the UI/DAL coupling.

How to fix

The rule lists which UI type uses which DAL type. More on this topic: http://www.kenneth-truyers.net/2013/05/12/the-n-layer-myth-and-basic-dependency-injection/

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>UI layer shouldn't use directly DAL layer</Name>
// <Id>ND1404:UILayerShouldntUseDirectlyDALLayer</Id>

warnif count > 0

// UI layer is made of types using a UI framework
let uiTypes = Application.Types.UsingAny(Assemblies.WithNameIn(
   "Microsoft.AspNetCore", "PresentationFramework", "System.Windows", "System.Windows.Forms", "System.Web"))

// Exclude commonly used DataSet and associated, from ADO.Net types
// 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"))

// DAL layer is made of types using a DB framework
// .ToHashSetEx() results to faster execution of    dalTypes.Intersect(uiType.TypesIUse).
let dalTypes = Application.Types.UsingAny(dbTypes).ToHashSetEx()

from uiType in uiTypes.UsingAny(dalTypes)
let dalTypesUsed = dalTypes.Intersect(uiType.TypesUsed)

let dalTypesAndMembersUsed = dalTypesUsed.Union(dalTypesUsed.ChildMembers().UsedBy(uiType))

// Per defaut this rule estimates a technical debt
// proportional to the coupling between the UI with the DAL layer. 
let couplingPerUIType = 2 +
   uiType.Methods.UsingAny(dalTypesUsed).Count() +
   dalTypesAndMembersUsed.Count()

select new {
   uiType,
   // if dalTypesUsed is empty, it means that the uiType is part of the DAL
   dalTypesAndMembersUsed,
   Debt = (4 * couplingPerUIType).ToMinutes().ToDebt(),
   Severity = Severity.High
}


//<Expl>
// The *{0}* shouldn't use directly *{1}* because doing so binds the UI layer directly with the DAL layer.
//</Expl>

//<Desc>
// A *sample rule to adapt to your need* showing how to define code layers
// and be warned about dependency violations. It checks if any UI layer type
// directly uses any DAL layer type.
//
// - **DAL (Data Access Layer)**: application types using *ADO.NET*,
// *EntityFramework*, *NHibernate* types (easy to adjust).
//
// - **UI layer**: types using *WPF*, *Windows Form*, *ASP.NET*.
//
// *UI using directly DAL* is *poor design*: DAL accesses should be hidden
// from UI in an **intermediary domain logic**. Estimated debt is
// proportional to the UI/DAL coupling.
//</Desc>

//<HowToFix>
// The rule lists which UI type uses which DAL type. More on this topic:
// http://www.kenneth-truyers.net/2013/05/12/the-n-layer-myth-and-basic-dependency-injection/
//</HowToFix>

Architecture: all 13 items