Defining Access Strategy in FluentNHibernate

I am posting this because it took me a little while (longer than it should have) to figure out how to define the access strategy for an domain object’s fields or properties. The documentation for FluentNHibernate is still fairly basic, and Googling for the answer didn’t get me anywhere. In the end I figured it out from Visual Studio’s intellisense (which frankly is where I should have looked in the first place).

For all those like me who decide to Google first, here is the answer.

A number of the *Part classes in the FluentNHibernate.Mapping namespace implement the IAccessStrategy(Of ComponentPart(Of T)) interface. This interface defines one property, Access which returns an AccessStrategyBuilder(Of T) object. The AccessStrategyBuilder object has a number of methods used to define the access strategy:

  • AsCamelCaseField
  • AsField
  • AsLowerCaseField
  • AsPascalCaseField
  • AsProperty
  • AsReadOnlyPropertyThroughCamelCaseField
  • AsReadOnlyPropertyThroughLowerCaseField
  • AsReadOnlyPropertyThroughPascalCaseField

This information I found relatively quickly. What I was missing was how to specify that my camel case fields are prefixed with the underscore character. But all of the CamelCase, LowerCase and PascalCase variations of the methods listed above have an overload which accepts an instance of a Prefix object, of which there are 4 variations:

  • m
  • mUnderscore
  • None
  • Underscore

So in the end, my mapping is as follows:


Id(Function(c) c.ID, "id").WithUnsavedValue(0).GeneratedBy.Identity()

Map(Function(c) c.AccountName).TheColumnNameIs("account_name")
Map(Function(c) c.Company).TheColumnNameIs("company")
Map(Function(c) c.Created).TheColumnNameIs("created")
Map(Function(c) c.Updated).TheColumnNameIs("updated")
Map(Function(c) c.UseAdministrativeContactAsBillingContact).TheColumnNameIs("blg_is_adm")

Component(Of Client)(Function(c) c.AdministrativeContact, _
                     AddressOf MapAdministrativeContact).Access.AsCamelCaseField(Prefix.Underscore)
Component(Of Client)(Function(c) c.BillingContact, _
                     AddressOf MapBillingContact).Access.AsCamelCaseField(Prefix.Underscore)

My First Extension Method

This evening I wrote my first VB.Net extension method while working on my S#arp Architecture based project. I added another overload of the TextBox method (which is itself an extension method, I believe). I wanted to be able to specify the size of the text box. One of the existing TextBox methods has the following signature:

HtmlHelper.TextBox(name As String, value As Object, htmlAttributes As IDictionary(Of String, Object))

I wanted to be able to specify a text box size without having to declare a new IDictionary every time. So I wrote the following extension method:

<Extension()> _
Public Function(html As HtmlHelper, name As String, value As Object, size As Integer)
    Dim attributes as IDictionary(Of String, Object) = New Dictionary(Of String, Object)

    attributes.Add("size", size)

    Return html.TextBox(name, value, attributes)
End Function

Neat stuff.

Now I just have to figure out how to create an extension method that will allow me to pass a lambda expression to RedirectToAction().

The Inner Workings of *.vbproj Files: <ProjectTypeGuids>

During the conversion of the S#arp Architecture template project from C# to VB.Net I inadvertently broke (at least) one thing: the ability to add ASP.Net MVC items directly to the SharpArch.Web project directly from the “Add New Items…” dialog. This led to my first question asked on (which I ended up answering myself, 38 minutes later).

Turns out Visual Studio project files can have an element called <ProjectTypeGuids> which contains one or more guids identifying what type of project the file describes. ASP.Net MVC projects have a particular guid specified: {603c0e0b-db56-11dc-be95-000d561079b0}.

So I added this guid to both my SharpArch.Web project file and my SharpArch.Controllers project file, and now I can add new MVC template items directly from the “Add New Item…” dialog. Cool!

S#arp Architecture

I’ve been poking around in the latest release of the S#arp Architecture over the last couple days. I like what I see.

Pronounced “Sharp Architecture,” this is a solid architectural foundation for rapidly building maintainable web applications leveraging the ASP.NET MVC framework with NHibernate.

This evening I took about an hour and converted the basic starter solution template from C# to VB.Net. Why? Well, for the following reasons:

  1. While I can work with C# well enough, I’m much more familiar with VB.Net, which I am required to use at my 9 to 5 job. I tend to stick with VB.Net even for my personal projects for simplicity. Anything I learn on my own I can easily apply at work.
  2. It gave me an opportunity to confirm that I understand (at least at a high level) what the S#arp Architecture is doing.

The conversion was straight forward. Pretty well every line of C# had a corresponding line in VB.Net. The only thing I had to add was an Imports tag in the markup of the Site.Master page in order to get the ActionLink and Image extension methods to resolve. I had already tried adding an imports to the code-behind with no luck. Not sure why that was necessary, but it worked.

The architecture is pretty neat. Here’s a few things I’ve noted already:

  • The Models, Views and Controllers (I.e. the M, V and C in MVC) are each in their own projects.
  • The Repository/IRepository pattern is used, with the Interfaces defined in the same project as the Models, and the Repository implementation(s) in a separate project.
  • Includes support for NUnit, Castle Windsor, (Fluent) NHibernate, and Rhino Mocks
  • The ASP.Net MVC routes are defined in the Controllers project, not in the Global.asax of the Web/Views project. Excellent separation of concerns!

I’m going to go ahead and trying putting together an actual application based on S#arp Architecture.

Tech Days Ottawa

I attended Tech Days in Ottawa this past Thursday. I stuck with the “Web Developer” stream all day and I have to say, I was a little disappointed.

To be fair I think I had very high expectations. I’ve been watching a lot of the PDC session videos online, videos of presentations by Oren Eini (aka Ayende Rahien) and attending Karl Seguin recent excellent presentation at ODNC. Needless to say, the people who presented at a one day conference in Ottawa (of all places) were not all of the same calibre. On top of that, the presentations and slide decks used are not created by the presenters. These are just people re-presenting someone else’s presentation (and in some cases re-telling someone else’s jokes).

The conference’s swag bag, or rather box, was a cereal box of “Techie Crunch” with some relatively good stuff including:

  1. 6 month TechNet subscription (but I already have a 1 year subscription)
  2. Full version of Visual Studio 2008 Professional (already have this too)
  3. Full version of Expression Web 2 (no source control support,  not even for Visual SourceSafe. BOO!)
  4. Full TechEd DVD set (this is actually AWESOME)

The last one includes hundreds of presentations, including the presentations I attend, but presented by the original presenters, by engaging and entertaining people.

Ironically, the best presentation I attended all day was given by a man with a primarily Unix/Linux background who nearly completely skipped over the Microsoft specific topics in the slide desk he was presenting.

Karl Seguin’s Foundations of Programming e-Book

I just finished reading Karl Seguin‘s excellent, and free, e-Book “Foundations of Programming“.

The book was brought to my attention via an invite to a lunch time session Karl is doing for the Ottawa .Net Community this Thursday. I find both the presentation and the e-book particularly timely as I am just recently getting into Test Driven Development (TDD), unit tests, mocking, Dependency Injection (DI) and Inversion of Control (IoC) frameworks.

Most of these things I’ve known about for some time, but I am just starting to actually use them all together, and I am finally starting to ‘grok’ them.

After reading the book I am looking forward to Karl’s presentation on Thursday all the more.

Investigating a .Net Web Application’s Performance Issues

Yesterday my boss and I meet with a group that has been having some significant performance issues with one of their web applications.

It’s a basic .Net web forms application (in C#). Their issue was that they had one page that was taking upwards of 75 seconds to load! Seriously. 75 seconds! They said they were using NHibernate and they had tracked the issue down to one method that was taking up the majority of those 75 seconds. They also said they had tried some direct database (Oracle) queries that returned MUCH faster than the NHibernate.

We suggested that they look at caching the results of the database queries and that they confirm exactly what queries NHibernate is making on their behalf (I think they assumed it would execute the same query they had tested directly, which may or may not be the case).

Now I am a fan of NHibernate, and I have done some things with it that resulted in less than stellar performance, but I’ve always found tweak things to near direct database performance levels without much effort by changing/correcting some basic assumptions I had about the data and model. So when I left the meeting I felt that NHibernate had unfairly been labelled as the source of the performance issues, so I decided to have a look at the code for myself.

After grabbing a local copy of the code from their source control repository, I ran the code in debug mode and quickly came to the conclusion that the method they had identified as taking a long time to execute was in fact really taking a long time to execute. So I had a closer look at that method, and here (essentially) is what I saw:

/* ... */
IQuery query = CreateQuery("SELECT ...");

for (i = 0; i < query.List().Count; i++)
    if ((!((object[])(new ArrayList(query.List())[i]))[0] == null) 
       && (!((object[])(new ArrayList(query.List())[i]))[2] == null))
        String value = (((object[])(new ArrayList(query.List())))[2]).ToString();
/* ... */

I am “paraphrasing” a bit (the real code was worse).

The query.List() call returns an IList instance containing all the results of the SQL query. I don’t know if each call to query.List() actually executes the database query again (there may be some caching involved somewhere) but each call to query.List() did involve some database activity (according to my network sniffer). You notice that query.List is being called 3 times per loop (in the real code it was more like 6 times per loop)!

Changing this code to make one call to query.List, storing the results in a local IList variable and subsequently re-using that local variable shaved nearly 50 seconds of the response time.

On top of that there would also be improvements by removing the code that creates 3 ArrayLists per loop (again in the real code, 6 ArrayLists per loop), copies the IList of database results into each ArrayList, uses each of those ArrayLists to access only one single item and them discards the ArrayLists (only to recreate them again on the next loop).

NHibernate wasn’t the source of their problem…

A Day Spent Refactoring Code

I spent a good part of today refactoring some code I’ve inherited. It’s a VB.Net wrapper around some commercial address verification software. Two examples of the type of functionality the software provides are address correction and address formatting.

Here is a simplified version of three of the classes I was given to work with: Address, CorrectedAddress and FormattedAddress. An Address is what you would provide to the verification software and the other two classes would be returned from either the address correction or address formatting functionality.

Public Class Address
    Public AddressLine As String
    Public City As String
    Public Province As String
    Public PostalCode As String
    Public Country As String
End Class
Public Class CorrectedAddress : Inherits Address
    Public Status As CorrectedAddress.Status
    Public Message As String

    Public Enum Status
    End Enum
End Class
Public Class FormattedAddress
    Public AddressLineOne As String
    Public AddressLineTwo As String
    Public AddressLineThree As String

    Public Status As FormattedAddress.Status
    Public Message As String

    Public Enum Status
    End Enum
End Class

Note that CorrectedAddress inherits from Address, but FormattedAddress does not. Both CorrectedAddress and FormattedAddress have a Status and Message properties (implemented as public fields above only for brevity). The Status properties both return similar, but not identical enumerations. In the actual code there were six classes like these two, but I am focusing only on these two for simplicity.

The whole thing didn’t seem quite right to me, and I struggled a bit to put my finger on how this should have been implemented. But then it hit me. CorrectedAddress isn’t really an Address. It’s a result of an address correction (that happens to have an address). “Is A” versus “Has A”. Remember the oft quoted Object-Oriented design principle:

Favour Composition over Inheritance

So I pulled the Address class out of the inheritance hierarchy, renamed CorrectedAddress and FormattedAddress to CorrectedResult and FormattedResult respectively and even threw in some Generics stuff to deal with the similar but different Status enumerations.

The result (the Address class was left as-is):

Public MustInherit Class Result(Of T As Structure)
    Public Status As T
    Public Message As String
End Class
Public Class CorrectedResult : Inherits Result(Of CorrectedResultStatus)
    Public Address As Address

    Public Enum CorrectedResultStatus
    End Enum
End Class
Public Class FormattedResult : Inherits Result(Of FormattedResultStatus
    Public AddressLineOne As String
    Public AddressLineTwo As String
    Public AddressLineThree As String

    Public Enum FormattedResultStatus
    End Enum
End Class

Much better!

Securing Web Services with SSL Client Certificates

I am posting this in the hopes that other poor souls writing .Net web service proxies to consume web services that require SSL client certificate authentication won’t waste days trying to figure out why their code isn’t working like every single related article on the web says it should.

According to just about every bit of information I could find on the web about using SSL client certificates with web service proxies, the following code should work:

Dim objCertificate As X509Certificate = X509Certificate.CreateFromCertFile(“C:\MyClientCert.cer”)

But that didn’t work for me, at least not out-of-the-box.

A bit more Googling uncovered this blog post by Kevin Hammond. The important points in his post were:

First, the certificate with the private key must be imported into your personal store.

When you import your certificate into the certificate store, you are presented with the option to “Enable strong private key protection. … Unfortuantely, enabling this option causes the .NET Framework to silently fail when accessing the private key of your certificate.

While this did not solve my problem (I had already done both of these things), it lead me to learn a bit more about this “personal store”. Among the things I learned is that there is a utility called WinHttpCertCfg.exe that can be used to manage the permissions of the certificate stores on your computer. Since my web service proxy was being called from an ASP.Net web page, the ASPNET user had to be given access to the certificate store containing the SSL client certificate.

But my SSL client certificate authentication was still not working. It had taken me the better part of a day to get to this point. What ended up taking me nearly three days to figure out was that there are a number of was to import SSL certificates into a certificate store. But only one way would work for my web service proxy. The break-through came from Matthew.DelVecchio who wrote in this news group post:

… added the Certifcates snap-in for the MMC windows management utility, and using it to delete my certs, re-add the .PFX into the “Personal” store, then exporting it to a .CER all w/ the MMC snap-in (and not using Control Panels -> Internet Settings or IE).

Hope this information helps someone out there save some time (and a little bit of sanity)!