CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Patrick Smacchia [MVP C#]


Dependencies and Concerns

Jim Bolla, a contributor to the NHibernate project, had a surprising remark while describing what NDepend has to say about the NHibernate code on its blog: 

(with NDepend) as an example, you can do stuff like this..

WARN IF Count > 0 IN SELECT METHODS WHERE IsDirectlyUsing "System.Web" AND IsDirectlyUsing "System.Data.SqlClient"

And you will get a result set of any methods in your project that are doing web stuff and SQL stuff in the same method! COOL! Now you know which n00b programmers you need to go slap mentor. In other words, you can define NDepend CQL queries to find methods that violate the Separation of Concerns principle.

 

The cool part is that using CQL constraints to enforce Separation of Concerns principle is something that we (the NDepend team) didn’t think about. Basically, tell me what you use and I can tell you what you are concerned about. This is a great idea! CQL comes with the direct dependencies conditions: IsDirectlyUsing / IsDirectlyUsedBy. For example:

// Which methods are directly calling a particular method
SELECT METHODS WHERE IsDirectlyUsing "MyNamespace.MyType.MyMethod()"

 

These conditions works on Assemblies/Namespaces/Types/Methods/Fields (ANTMF) and you can mix domains for example:

// Which assemblies are directly using a particular method?
SELECT
ASSEMBLIES WHERE IsDirectlyUsing "MyNamespace.MyType.MyMethod()" 

 

// Which types are directly used by a particular assembly?
SELECT TYPES WHERE IsDirectlyUsedBy "MyAssembly"


// Which namespaces are directly using a particular field?
SELECT NAMESPACES WHERE IsDirectlyUsing "MyNamespace.MyType.m_Field"

 

You can mix these conditions with all CQL facilities for example:

SELECT TYPES FROM ASSEMBLIES "MyAssemblyA" WHERE IsDirectlyUsing "MyAssemblyB"

 

Or:

SELECT METHODS OUT OF NAMESPACES "MyNamespace" WHERE IsDirectlyUsing "MyType"

 

As pointed Jim, you can enforce some separation of concerns by mixing several direct dependencies conditions in the same constraint. Alternatively you can also make sure that an API is used as it should be. Often there are situations where doing something implies doing another things. For example this constraint warns if a method tries to delete a file but is not using the class IOException:

WARN IF Count > 0 IN SELECT METHODS WHERE
IsDirectlyUsing
"System.IO.File.Delete(String)" AND !IsDirectlyUsing "System.IO.IOException"

 

You can also readily write any kind of constraint to force the use of interfaces instead of classes:

WARN IF Count > 0 IN SELECT METHODS WHERE
IsDirectlyUsing
"MyNamespace.MyType" AND !IsDirectlyUsing "MyNamespace.IMyInterface"

 

The following constraints warns when a method obtains a Graphics from an image and doesn’t call the Dispose() method:

WARN IF Count > 0 IN SELECT METHODS WHERE
IsDirectlyUsing
"System.Drawing.Graphics.FromImage(Image)" AND !IsDirectlyUsing "System.IDisposable.Dispose()"

 

 

If you are developing a framework, you can build a set of such constraints that your clients should applies to make sure that they are using your framework correctly.

 

Another use of mutiple IsDirectlyUsing conditions is to guess where an API should be used. For example, this query matches methods that are changing some states and that are not using any synchronization API:

SELECT METHODS WHERE !(
   IsDirectlyUsing
"System.Threading.Mutex" OR
   IsDirectlyUsing
"System.Threading.Interlocked" OR
   IsDirectlyUsing
"System.Threading.Monitor" OR
   IsDirectlyUsing
"System.Threading.ReaderWriterLock") AND
(
ChangesObjectState OR ChangesTypeState) AND
!(
IsConstructor OR IsClassConstructor)

 

Another idea is to make sure that the layer represented by the code in the namespace MyNamespace  is not entangled with any other namespaces (i.e has no bi-directional dependency with any other namespace):

WARN IF Count > 0 IN SELECT NAMESPACES WHERE
IsDirectlyUsing
"MyNamespace" AND IsDirectlyUsedBy "MyNamespace"

 

I will certainly post more on these. Thanks to its flexibility CQL offers a wide range of possibilities to explore!



Comments

Paul Kinlan’s .Net Development Blog » Goolgle Reader Shared items for 1970-01-01 said:

Pingback from  Paul Kinlan’s .Net Development Blog » Goolgle Reader Shared items for 1970-01-01

# April 4, 2008 5:37 PM

Paul Kinlan’s .Net Development Blog » Goohle Reader Updates for 1970-01-01 said:

Pingback from  Paul Kinlan’s .Net Development Blog » Goohle Reader Updates for 1970-01-01

# April 4, 2008 5:44 PM

Paul Kinlan’s .Net Development Blog » Goohle Reader Updates for 1970-01-01 said:

Pingback from  Paul Kinlan’s .Net Development Blog » Goohle Reader Updates for 1970-01-01

# April 4, 2008 5:47 PM

Paul Kinlan’s .Net Development Blog » Goohle Reader Updates for 1970-01-01 said:

Pingback from  Paul Kinlan’s .Net Development Blog » Goohle Reader Updates for 1970-01-01

# April 4, 2008 5:48 PM

Paul Kinlan’s .Net Development Blog » Goohle Reader Updates for 1970-01-01 said:

Pingback from  Paul Kinlan’s .Net Development Blog » Goohle Reader Updates for 1970-01-01

# April 4, 2008 5:49 PM

Paul Kinlan’s Development Blog » Shared Google Reader Items for 2008-04-04 said:

Pingback from  Paul Kinlan’s Development Blog » Shared Google Reader Items for 2008-04-04

# April 4, 2008 9:52 PM

Patrick Smacchia [MVP C#] said:

Recently, both Glenn Block and Ayende wrote about how to define some sort of active conventions about

# May 11, 2008 4:53 PM

Community Blogs said:

Recently, both Glenn Block and Ayende wrote about how to define some sort of active conventions about

# May 12, 2008 3:45 AM

Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add

About Patrick Smacchia

Patrick Smacchia is a Visual C# MVP involved in software development for over 15 years. After graduating in mathematics and computer science, he has worked on software in a variety of fields including stock exchange, airline ticket reservation system as well as a satellite base station at Alcatel. He's currently a software consultant and trainer on .NET technologies as well as the lead developer of the tool NDepend which provides numerous metrics and caveats on any compiled .NET application. He is the author of Practical .NET2 and C#2, a .NET book conceived from real world experience with 647 compilable code listings. Check out Devlicio.us!