NHibernate 2.1 Changes Overview

Normal

0

21

false

false

false

FR

X-NONE

X-NONE

Share/Bookmark

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
(+60.7%).

 

Methods
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


 

This
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

 

There are
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

Knowing which
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.

 

The answer
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.

 

If you are
not acquainted with reading a dependency matrix, then certainly a dependency
graph
of the situation will make things more clearer:

 

 

 

Breaking Changes

30 public
types were removed which can then constitute a breaking change.

SELECT TYPES WHERE IsPublic AND WasRemoved

 

Quality through Code Metrics

When asking
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
refactor
</Name>

WARN IF Count > 0 IN SELECT METHODS WHERE

     (  NbLinesOfCode > 30 OR         

        CyclomaticComplexity > 20 OR  

        ILNestingDepth > 4 OR         

        NbParameters > 5 OR           

        NbVariables > 8               

        ) 

 

Test Organization

As many
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:

This
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:

Normal

0

21

false

false

false

FR

X-NONE

X-NONE

<?xml version=1.0 encoding=utf-8 ?>

<configuration>

  <runtime>

    <assemblyBinding xmlns=urn:schemas-microsoft-com:asm.v1>

      <probing privatePath=Debug;Debug\Lib1;Debug\Lib2 />

    </assemblyBinding>

  </runtime>

</configuration>

 

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.

Share/Bookmark

This entry was posted in breaking changes, Changes, code structure, CopyLocal syndrome, Dependency Graph, Dependency Matrix, entangled, Metric View, namespaces, NHibernate. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Emmanuel Champommier

    By the way,
    NHibernate now depends from Antlr3.runtime, which does not have CLSCompliant attribute set to true.
    I planned to use it from a VB.NET client application. What do you think ?

  • http://codebetter.com/members/Patrick-Smacchia/default.aspx Patrick Smacchia

    joseilto, contact me and I’ll send you the examples: psmacchia NOSP at google mail

  • joselito

    Where is possibkle to find exemple from practical .net2 and C#2
    It’s my bible put i lost the file.

    A possibility to hope a book for .Net3.5?

  • http://codebetter.com/members/Patrick-Smacchia/default.aspx Patrick Smacchia

    DaRage, could you send me the source of the NServiceBus version you wish to have a glimpse? psmacchia NOSP at google mail. Thanks

  • DaRage

    Hi Patrick, can you do an analysis of nServiceBus?They released 1.9 not too long ago. I looked at the code and it seemed very well structured according to namespaces and assemblies, but I’m curious what will NDepend find.

    Thanks

  • http://codebetter.com/members/Patrick-Smacchia/default.aspx Patrick Smacchia

    woaksie, you have to define the build compilation order by yourself by relying on: Solution Epxlorer > Right click project > Project Dependencies / Build order

  • http://comichour.com/ woaksie

    I am interesting in your findings re: copy local. If you reference by assembly in a common output folder can you rely on VS to build the projects in the right order or do you have to make sure the build order is correct yourself?

    P.S. I like the captcha

  • http://codebetter.com/members/Patrick-Smacchia/default.aspx Patrick Smacchia

    Caustic, if you read the following post I wrote 3 weeks ago I just come to the exact same conclusion as you:

    http://codebetter.com/blogs/patricksmacchia/archive/2009/06/28/fighting-fabricated-complexity.aspx

    From the post:

    >I would prefer to avoid giving the NDepend user the feeling that fighting fabricated complexity is only a matter of reducing the value of a naked index

    As every time I shed light to some non-positive facts buried in a code base I get the same critic again and again: You believe too much in metrics basically (which I don’t, read my post)

    Caustic you wrote:

    >The numbers themselves tell you nothing

    I don’t agree. Numbers can hardly prove if something is good but they are drastically efficient at showing bad things like:

    -methods with 300 lines of code or 15 parameters or 20 variable…

    -5% code coverage by tests

    -a class that use 167 other classes

    -a field that is written by 10 different methods

    -a method with 20 overloads

    -a class with a depth of inheritance of 10

    -an application partitionned in 785 assemblies

    all these things are part of the real-world horoor I saw :o/

  • http://www.pluralsight.com .NET Training

    The most comprehensive .NET Training available

  • http://www.causticmango.com caustic

    Having some experience with software metrics dating back to the mid 90′s, I take issue with your premise that you can judge the quality of any codebase based solely on the specific values of any set of metrics.

    The numbers themselves tell you nothing — the only interesting metrics are those that are changing either over time, in context with other parts of the codebase or in comparison to a similar codebase.

    Your desire to find a suite of magical benchmark metrics that will tell you “this code is ‘good’” and “this code is ‘bad’” is a common one, but many years of experience has convinced me this is a misguided quest.

    Even the visionaries in the field (like Tom Demarco) will caution against this. Fight the urge to find too much meaning in the numbers the metrics tools spit out.

  • http://blogs.imeta.co.uk/sstrong Steve Strong

    Nice post, and it’s kind of cool to see the stuff I’ve been working on so prominent in the first diagram :) It’s worth clarifying two points though:

    * The bulk of what I did was porting from Java Hibernate, so I don’t in any way claim to have written quite as much code as it may appear (plus ANTLR generated rather large swathes of it)

    * We still don’t have the full Linq provider ready; the AST parser is the key building block, and it’s great that it made it into 2.1, but the full Linq provider is still under development. It’ll definitely be there for 3.0, and possibly on a future 2.1.x branch as well. Watch my blog or twitter feed for updates…

  • http://jonorossi.com/ Jonathon Rossi

    Dominic, you are right, you can now pick from Castle, LinFu or Spring for proxy generation.

    The implementation of each are in the NHibernate.ByteCode.*.dlls, which also need to be shipped along with the chosen proxy generation library.

  • http://codebetter.com/members/Patrick-Smacchia/default.aspx Patrick Smacchia

    Dominic, your remark is relevant. I hope that some NHibernate insiders will be able to shed light on this part.

    I am by no mean a NHibernate nor Castle expert but it seems that if NHibernate is using Castle through IoC, NHibernate.dll should reference some kind of Castle.Interfaces.dll right?

  • http://www.dominicpettifer.co.uk Dominic Pettifer

    You say it no longer uses Castle but the dlls are still in the version 2.1 download. But there’s also Spring.net and something called LinFu. Are dynamic proxy engines somehow being dynamically loaded in now (rather than depend on just Castle)?

    Excuse my ignorance, the stuff is slightly above my level of experience, I’ve only just started using IOC containers.