I have been working with NHibernate for manner of couple of years and I never seriously thought about how it is built from inside, what is the architecture of NH, how much it depends on ADO.NET, how they made reflection to work fast, how high code quality is, which people worked on it and what was the history of it. The other day, I had chance to start mine own small ORM project and all of this questions raised for me. Thus I will do my best to share everything I discovered in NHibernate surgery.
3. NHibernate guts. Why?
And not so scary as you could have thought
http://andriybuday.com | http://kievalt.net
4. Outline
Q1: If build similar ORM ourselves?
Q2: How does it look like at glance?
History
Community
Code base quality
Q3: Dive deeper?
Main interaction classes
DEMO 1: Debugging fetch logic
DEMO 2: Debugging save logic
Let see… if guts could be interesting o_O
http://andriybuday.com | http://kievalt.net
5. Q1: If build similar ORM ourselves?
Lets draw…
http://andriybuday.com | http://kievalt.net
6. Q1: If build similar ORM ourselves?
This might be the solution we came up with…
Even uglier than real cave drawing
http://andriybuday.com | http://kievalt.net
7. Q2: How does it look like at glance?
History
http://andriybuday.com | http://kievalt.net
8. Q2: How does it look like at glance?
Community
http://andriybuday.com | http://kievalt.net
9. Q2: How does it look like at glance?
NDepend analysis
http://andriybuday.com | http://kievalt.net
10. Q2: How does it look like at glance?
NDepend analysis: Application Metrics
L. of code : 62,914 Fields : 7,205
L. of comment: 37,113 C# source files : 1,437
Assemblies : 3 IL instruction : 437,982
Namespaces : 90 Classes : 1,866
Types : 2,211 UT coverage: 75.93%
Methods : 18,335
http://andriybuday.com | http://kievalt.net
11. Q2: How does it look like at glance?
Architecture: entity states
http://andriybuday.com | http://kievalt.net
12. Q2: How does it look like at glance?
Architecture: more
http://andriybuday.com | http://kievalt.net
13. Q2: How does it look like at glance?
Personal opinion: really well-commented
/// <summary>
/// Get the alias of the entity encapsulated by this criteria instance.
/// </summary>
/// <value>The alias for the encapsulated entity.</value>
string Alias { get; }
/// <summary>
/// Was the read-only mode explicitly initialized?
/// </summary>
/// <returns><c>true</c> if the read-only mode was explicitly initialized, otherwise <c>false</c>.</returns>
/// <seealso cref="ICriteria.SetReadOnly(bool)" />
/// <seealso cref="ICriteria.IsReadOnly" />///
bool IsReadOnlyInitialized { get; }
/// <summary>
/// Will entities (and proxies) loaded by this Criteria be put in read-only mode?
/// </summary>
/// <remarks>
/// <para>
/// If the read-only setting was not initialized, then the value of the session's
/// <see cref="ISession.DefaultReadOnly" /> property is returned instead.
/// </para>
/// <para>
/// The read-only setting has no impact on entities or proxies returned by the
/// Criteria that existed in the session before the Criteria was executed.
/// </para>
/// </remarks>
/// <returns>
/// <c>true</c> if entities and proxies loaded by the criteria will be put in read-only mode,
/// otherwise <c>false</c>.
/// </returns>
/// <seealso cref="ICriteria.SetReadOnly(bool)" />
/// <seealso cref="ICriteria.IsReadOnlyInitialized" />
bool IsReadOnly { get; }
/// <summary>
/// Used to specify that the query results will be a projection (scalar in
/// nature). Implicitly specifies the projection result transformer.
/// </summary>
/// <param name="projection">The projection representing the overall "shape" of the
/// query results.</param>
/// <returns>This instance (for method chaining)</returns>
/// <remarks>
/// <para>
/// The individual components contained within the given <see cref="IProjection"/>
/// determines the overall "shape" of the query result.
/// </para>
/// </remarks>
ICriteria SetProjection(params IProjection[] projection);
Don’t read code – see how green it is
http://andriybuday.com | http://kievalt.net
14. Q2: How does it look like at glance?
Personal opinion: a lot of noise in code
if (cmd.Connection != null)
{
// make sure the commands connection is the same as the Sessions connection
// these can be different when the session is disconnected and then reconnected
if (cmd.Connection != sessionConnection)
{
cmd.Connection = sessionConnection;
}
}
else
{
cmd.Connection = sessionConnection;
}
Now read code!
Don’t you think it can be replaced?
cmd.Connection = sessionConnection;
http://andriybuday.com | http://kievalt.net
15. Q3: Dive deeper?
Lets have some fun with code & debugging…
http://andriybuday.com | http://kievalt.net
16. Q3: Dive deeper?
Lets have some fun with code & debugging…
Overview
DEMO 1: Debugging fetch
DEMO 2: Debugging save
http://andriybuday.com | http://kievalt.net
17. Questions?
Ask me something! But easy!
http://andriybuday.com | http://kievalt.net
19. Links
My blog:
http://andriybuday.com
Kiev ALT.NET:
http://kievalt.net/
NHibernate:
Home Page: http://nhforge.org/
Source Code: https://github.com/nhibernate/nhibernate-core
Screencasts: http://www.summerofnhibernate.com/
Reference: http://www.nhforge.org/doc/nh/en/index.html
NDepend analysis:
http://www.ndepend.com/SampleReports/OnNHibernate/NDependReport.html
So what’s NH development look like: http://elegantcode.com/2008/12/07/so-
whats-nhibernate-development-like/
Mapping by code:
http://fabiomaulo.blogspot.com/2011/04/nhibernate-32-mapping-by-code.html
http://andriybuday.com | http://kievalt.net
Editor's Notes
Hello, Kiev ALT.NET!
Invented in early 1990’sOne of the first came from ClevelandRaleigh Systems’ ObjectPMShield the OO application from the database paradigmMappings to tables and columns are localized in configuration filesInitially developed for Javacreated in late 2001 by Gavin Kingabsorbed by the JBoss Group / Red HatPorted to .NET 1.1 and 2.0Resulting product called “NHibernate”All popular databases supportedXML-based configuration files----------------NHibernate was started by Tom Barrett, and later picked up by Mike Doerfler and Peter Smulovics. Now Fabio Maulo is the project leader. At the end of 2005, JBoss, Inc. (now part of Red Hat) hired Sergey Koshcheyev, the then lead developer of NHibernate, to work full-time on its future versions.[2] At the end of 2006 JBoss stopped the support to this project; it is now entirely developed and led by the community.Version 1.0 mirrored the feature set of Hibernate 2.1, as well as a number of features from Hibernate 3.NHibernate 1.2.1, released in November 2007, introduced many more features from Hibernate 3 and support for .NET 2.0, stored procedures, generics, and nullable types.NHibernate 2.0 was released August 23, 2008. It is comparable to Hibernate 3.2 in terms of features. With the version 2.0 release, NHibernate dropped support for .NET 1.1.[3]NHibernate 2.1 was released July 17, 2009.NHibernate 3.0 was released on December 04, 2010 and is the first version to use .NET 3.5. Introduces integrated LINQ support and also strongly typed criteria-like API called QueryOver, new AST-based parser for NHibernate's HQL (Hibernate Query Language) engine, support for lazy loading columns.NHibernate 3.2 has been released recently.[edit] What is new in NHibernate 3.2Some of the new Features are [4]Mapping by code: fluent configuration, no more .hbm.xml files required;Subselect: ability to map SQL views as entities;HQL paging: TAKE and SKIP on HQL;Integrated bytecode provider: one less DLL to deploy.----------------