A year ago,
when NHibernate 2.0 was released I did a NHibernate 2.0 Changes Overview post.
Today NHibernate 2.1 is out so let’s have a look at what’s new. One can
consider this 2.1 release as a major release. The code base size increased from
36.143 to 58.082 Lines of Code
added or changed represent 67% of the code base! The metric view below speaks
for itself (rectangles are methods, rectangle surface is proportional to
corresponding method’s number of lines of code, blue rectangles represent
methods added or changed):
SELECT METHODS WHERE CodeWasChanged OR WasAdded
snapshot shows how prevalent is the new NHibernate.Hql implementation developed
by Steve Strong
to support Linq in NHibernate v2.1. This new implementation represents almost
20K lines of code (the bulk of this is generated by ANTLR) and you can have a
glance below at the 239 public types added just for that purpose.
SELECT TYPES FROM NAMESPACES “NHibernate.Hql.*” WHERE IsPublic AND WasAdded
many others new public types that you can browse here.
SELECT TYPES OUT OF NAMESPACES “NHibernate.Hql.*” WHERE IsPublic AND WasAdded
Library used by NHibernate
particular libraries a code base is consuming is precious information. And
indeed, by just having a glance at tier assemblies used by NHibernate (2.0 vs.
2.1) one can certainly infer some interesting remarks about decision taken.
stroked blue assemblies are not used anymore, bold assemblies are used by v2.1 but not
be v2.0, the set of members/types used of underlined assemblies has
changed between the 2 versions, while the set of members/types used of not-underlined
assemblies is the same across the 2 versions.
Code still entangled
In my post
on NHibernate v2.0, I had a critic concerning the lack of structuration of the
NHibernate code base. Unfortunately, as shown on the dependency matrix below,
the situation hasn’t changed. The fact that almost all cells are black means
that each namespaces depends directly or indirectly on all other namespaces.
of NHibernate coders to this critic is that they have to stick with the Java
Nhibernate architecture that is entangled. NHibernate is a great framework useful
to thousands of project worldwide. Rationalizing its code structure would be a
favor that NHibernate coder could do to themselves. Now, the code base is completely
entangled and it must be a daily pain to maintain the code. There is a total
lack of componentization and each modification might potentially affect the
whole code base. Btw, last year one of the former NHibernate coder told me privately
that he quitted the project especially because of this spaghetti problem.
types were removed which can then constitute a breaking change.
SELECT TYPES WHERE IsPublic AND WasRemoved
Quality through Code Metrics
for complex methods that needs refactoring 637 methods are matched. This might
sounds a lot but if you look at respective metrics values you’ll see that the
bulk of matched methods only slightly exceed fixed thresholds.
// <Name>Quick summary of methods to
WARN IF Count > 0 IN SELECT METHODS WHERE
( NbLinesOfCode > 30 OR
CyclomaticComplexity > 20 OR
ILNestingDepth > 4 OR
NbParameters > 5 OR
NbVariables > 8
other .NET code base, NHibernate suffers from the CopyLocal set to true syndrome. I described this syndrome while
analyzing the NUnit code base
and demonstrated that not using this silly VisualStudio default option can optimize
a lot compilation duration and also disk space.I reported this problem to Rico Mariani in charge of VSTS 2010 performance and I hope they will be able to find a workaround, or at the very least make CopyLocal set to false by default
Here is the result of
assemblies duplication after compilation:
assembly duplication comes from the fact that each test project copies locally
its own version of NHibernate.dll. The
only correct answer I found to this issue is to spit the test assemblies in a
parent folder of the folder that hosts the application assemblies. Something like
test assemblies in $root$\bin and
application assemblies in $root$\bin\Debug.
Then, to redirect the CLR assembly referenced probing algo at test-run time, you
just need to use an App.config file for each test assembly, that look like:
<?xml version=“1.0“ encoding=“utf-8“ ?>
<probing privatePath=“Debug;Debug\Lib1;Debug\Lib2“ />
As a final
remark let me precise that I have a great respect for the work achieved and the
large adoption of this OSS project. My critic about the lack clear
componentization is not a critic of the work done by NHibernate developers,
that have to abide by the Hibernate old brother structure. It is a remark that,
I am sure, could make their life much easier.