Are you using NHibernate or other open-source library in your project? I’m pretty sure that you are. Have you ever wondered what’s happening “under the cover” when you call Session.Get
or perform a query? You probably did. The problem is that usually all the external assemblies are stored in one directory (libs, packages, reflibs, etc.) with no symbol files or sources. In this post, I would like to show you how you can easily get profit of project’s ReferencePath
property and debug the source code of your libraries at any time you want.
Let’s assume that our projects are using NHibernate 3.1. We ran nuget (http://nuget.codeplex.com/) to setup dependencies and NHibernate libraries are now in $(ProjectDir)\packages\NHibernate.3.1.0.4000\lib\Net35. In the project file (.csproj), we probably have the following section:
<Reference Include="NHibernate">
<HintPath>packages\NHibernate.3.1.0.4000\lib\Net35\NHibernate.dll</HintPath>
</Reference>
We are also using code repository and our .csproj file is checked-in as well as the whole packages directory. One day, we noticed that one repository (DAO) function was performing really badly. While debugging, we found out that the problem lies in Session.Get
method. Without any knowledge about what’s happening inside, we were not able to tell what causes this performance loss. But we also knew that NHibernate library is open-source so we got the source codes, debugged it and had a grasp at what NHibernate gurus put in there. We downloaded the source codes (NHibernate-3.1.0.GA-src.zip), saved them to c:\NHibernate-src and ran the compilation script (NHibernate was using nant script, we wanted PDB files that’s why project.config=debug
, I skipped tests just to speed up the build process):
nant -t:net-3.5 -D:skip.tests=true -D:skip.manual=true -D:project.config=debug
You probably will need to download ILMerge and place it in the c:\NHibernate-src\Tools\ILMerge. I also needed to remove c:\NHibernate-src\src\NHibernate.Test.build – somehow I was getting compilation errors and didn’t have time to check why (we won’t need the NHibernate.Test.dll anyhow).
The question now is how to bind the newly compiled assemblies (from c:\NHibernate-src\build\NHibernate-3.1.0.GA-debug\bin\net-3.5\) with our projects. There are two approaches: we can either replace NHibernate references in all projects and copy our debug-enabled binaries to packages\NHibernate.3.1.0.4000\lib\Net35 folder or use ReferencePath
properties. The first approach has many disadvantages – we are messing project files used by all developers (.csproj), the source code is on our machine so other users won’t be able to debug NHibernate, on deployment, we will need to restore all release-compiled binaries. When using ReferencePath
, we don’t have such problems. ReferencePath
is your local project property and is stored in .csproj.user file which you usually doesn’t upload to the repository (and if you do, you shouldn’t ). Visual Studio considers ReferencePath
in the first place (before HintPath
) while looking for assemblies and so when you compile your project locally, it will be bound with the debug-enabled assemblies. Just to finish the subject: you set the ReferencePath
by right clicking your project in Solution Explorer, choosing Properties and then ReferencePaths
tab:
Click “Add Folder” and a new section should appear in your .csproj.user file:
<PropertyGroup>
<ReferencePath>c:\NHibernate-src\build\NHibernate-3.1.0.GA-debug\bin\net-3.5\
</ReferencePath>
</PropertyGroup>
Now, while debugging, press F11 on Session.Get
and you should be able to step NHibernate source code. Have fun!
Filed under: CodeProject, Debugging, NHibernate, Visual Studio