Browsing Posts in .NET General

factory_girl.jpgAs some of you might have noticed, I’ve been talking about Ruby and Ruby on Rails more recently. It’s often good to get outside your comfort zone and see how other (web) developers live. One of the areas where Ruby really excels is the wealth of innovative testing/spec’ing libraries available. When writing tests/specs, we need objects to play with. Ruby has a variety of options in this regard, but I particularly like the factory approach espoused by gems such as factory_girl or machinist. I’m partial to factory_girl. So let’s take a look at the syntax and see if we can create something similar for .NET. First off, let’s take a look at the usage syntax:

describe Site do
  it "should register a new user" do  
    user = FactoryGirl.build(:user)
    site = Site.new
    site.register(user)
    site.users.should include(user)
  end
end

If we want to customize the instance, we can do that too by passing in a hash as the second argument:

describe Site do
  it "should not register new admin users" do
    user = FactoryGirl.build(:user, :admin => true)
    site = Site.new
    site.register(user)
    site.should_not include(user)
  end
end

What is interesting about factory_girl is that we can create instances of objects without the visual clutter of irrelevant properties. A user requires a first and last name, but in the above cases, we don’t care what they are. In the second case, we can see that the user being an admin is important for this test/spec. By removing the irrelevant properties, we can quickly see at a glance the data that matters for this spec. We also have the advantage that as properties are added to the User class, we have one place to update them (e.g. in the factory_girl definition) and we don’t have to wade back through all our tests adding values for required properties.

ASIDE: Now you might be tempted to say that we’ve been doing something like this in .NET with the Object Mother pattern. The Object Mother pattern is a factory of sorts. The problem is that it tends to be a dumping ground for different variations of the test objects. For example, ObjectMother.CreateUser(), ObjectMother.CreateAdminUser(), ObjectMother.CreateUserWithFirstName(string firstName), ObjectMother.CreateAdminUserWithFirstName(string firstName). The result is a tightly-coupled big ball of testing mud where the team is loathe to re-use ObjectMother methods for fear of breaking other tests. So you end up with this sprawling mass of methods for creating test data, which is separated from the tests themselves. Not a good place to be in.

Let’s look at the syntax for defining our factories in factory_girl:

FactoryGirl.define do
  factory :user do
    first_name 'John'
    last_name  'Doe'
    admin      false
  end
end

There is a lot more to factory_girl than I’ve covered above. When defining factories, you can create associations, lazy attributes, aliases, sequences, callbacks, and much more to keep your factories clean, lean, and mean. When using the factories, there is more than just FactoryGirl.build. There is also FactoryGirl.create, which saves the built instance to the database, FactoryGirl.attributes_for, which provides you with a hash of values often useful for testing Controller create actions, and FactoryGirl.build_stubbed, which returns a stubbed out instance. Here we’re going to focus on FactoryGirl.build to see how close we can get to the Ruby syntax, but written in C#.

Let’s start by looking at what our definition syntax could look like in C#.


FactoryGirl.Define(() => new User());


We give FactoryGirl a Func<T> that creates an instance of the object. Note the use of C# type inferencing so that we don’t have to specify the generic method argument on FactoryGirl.Define.


public static class FactoryGirl {
  private static readonly IDictionary<Type, Func<object>> builders = new Dictinonary<Type, Func<object>>();

  public static void Define<T>(Func<T> builder) {
    if(builders.ContainsKey(typeof(T))) throw new DuplicateFactoryException();
    builders.Add(typeof(T), () => builder());
  }
}


Basically I’m just keeping a hash table of Type versus Func<T>. That way when I get asked to build an object later, I can look it up and run the Func<T>. I have to play some games with the C# type system. My hash table has to store Func<object> because the generic parameter is declared on the methods, not the class. C# is also not able to implicitly convert Func<T> to Func<object>. So I have to add a lambda to the hash table that calls the builder rather than adding the builder directly.


builders.Add(typeof(T), builder); // Compiler error


Whereas the following makes the C# compiler happy.


builders.Add(typeof(T), () => builder()); // Compiler is happy


Now let’s look at the API for building an object.


var user = FactoryGirl.Build<User>();


From an implementation standpoint, we simply need to find the appropriate Func<T> and execute it.

public static class FactoryGirl {
  public static T Build<T>() {
    return (T) builders[typeof(T)];
  }
}


Simple enough. Now if we want to customize the object built…


var admin = FactoryGirl.Build<User>(x => x.Admin = true);


We really just need to accept an Action<T>, which we will execute after the object is constructed.

public static class FactoryGirl {
  public static T Build<T>(Action<T> overrides) {
    var result = (T) builders[typeof(T)];
    overrides(result);
    return result;
  }
}


With this simple implementation, we now have a central place to define our factories and build objects. Any customizations required are in the tests/specs themselves making it easier to understand our intentions in the tests/specs. When we add a new required property, we need to simply update our factory definition with an appropriate default. If needed, you can easily call FactoryGirl.Build() from within a factory definition. I have used this FactoryGirl technique in a production application and it dramatically cleaned up our specification code as compared to a previous project that used Object Mother. I hope it gives you some ideas of how to clean up your own test/spec code. If you are curious about the code or interested in extending FactoryGirl.NET to add some missing capabilities, such as Create, AttributesFor, BuildStubbed, or anything else, you can find the code on GitHub.com here.

UPDATE: A few people have asked me about customizing multiple properties when building an object. FactoryGirl.NET already supports this using the following syntax:

var user = FactoryGirl.Build<User>(x => {
                x.Admin = true;
                x.Age = 42;
           });

Once upon a time there were four friends – two TextBoxes and two ComboBoxes. They all lived happily on a WPF Window bound together in blissful MVVM harmony. The TextBoxes were bound to the ViewModel’s TextBoxText property and the ComboBoxes to the ComboBoxSelectedItem property.

MVVM ComboBox

<Window x:Class="MvvmComboBox.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:mvvm="clr-namespace:MvvmComboBox" 
        Title="MVVM ComboBox" Width="300" Height="150">
    <Window.Resources>
        <mvvm:MainWindowViewModel x:Key="viewModel"/>
    </Window.Resources>
    <StackPanel DataContext="{StaticResource viewModel}">
        <TextBox Text="{Binding TextBoxText.Value}"/>
        <TextBox Text="{Binding TextBoxText.Value}"/>
        <ComboBox ItemsSource="{Binding ComboBoxItems}" 
                SelectedItem="{Binding ComboBoxSelectedItem.Value}"/>
        <ComboBox ItemsSource="{Binding ComboBoxItems}" 
                SelectedItem="{Binding ComboBoxSelectedItem.Value}"/>
    </StackPanel>
</Window>

TextBoxText and ComboBoxItem are both Observable<T> so that INotifyPropertyChanged notifications are broadcast properly to all interested parties.

public class Observable<T> : INotifyPropertyChanged where T:class {
    public event PropertyChangedEventHandler PropertyChanged = (o,e) => { };

    private T value;
    public T Value {
        get { return value; }
        set {
            if(this.value == value) return;
            this.value = value;
            PropertyChanged(this, new PropertyChangedEventArgs("Value"));
        }
    }
}

ASIDE: Notice the event definition in line 2. By assigned a NOP (no operation) lambda, I don’t have to check whether any listeners are registered for the event. I can simply fire the event and worse case scenario, I execute an empty function body rather than throwing a NullReferenceException. This is tidier in my opinion than the if(PropertyChanged != null) nonsense that we’ve been using for years.

The view model is similarly simple.

public class MainWindowViewModel {
    public MainWindowViewModel() {
        TextBoxText = new Observable<string>();
        ComboBoxSelectedItem = new Observable<string>();
    }

    public Observable<string> TextBoxText { get; set; }
    public Observable<string> ComboBoxSelectedItem { get; set; }

    public IEnumerable<string> ComboBoxItems {
        get {
            yield return "One";
            yield return "Two";
            yield return "Three";
            yield return "Four";
            yield return "Five";
        }
    }
}

With the INotifyPropetyChanged in place, changing one TextBox will cause its twin to display the same value and same for the two ComboBoxes.

MVVM ComboBox synchronized

We get a strange new requirement that every second change should be ignored. (The actual business requirement was more sensible. I was displaying a list of entities for editing. If the previous entity wasn’t saved, the user would be presented with a save dialog and standard “yes/no/cancel” options. On cancel, I wanted to disregard the ComboBox change and revert back to the previously selected entity.)

public class Observable<T> : INotifyPropertyChanged where T:class {
    public event PropertyChangedEventHandler PropertyChanged = (o,e) => { };

    private T value;
    private int count;
    public T Value {
        get { return value; }
        set {
            if(this.value == value) return;
 
            if(count++ % 2 == 0) return;
 
            this.value = value;
            PropertyChanged(this, new PropertyChangedEventArgs("Value"));
        }
    }
}

So based on business rules, we’ve ignored a change to the view model. The TextBoxes always remain synchronized – reverting back to the previous value if the change is ignored. Unfortunately the changed ComboBoxes becomes unsynchronized with the view model if the view model ignores a change.

MVVM ComboBox unsynchronized

If you examine the view model in the debugger, the TextBoxText is “Hello, world! Hello, again!” as expected. You can change either TextBox as many times as you want. Every other edit is ignored and causes its changes to revert, as expected. Examining the current state of the view model’s ComboBoxSelectedItem, its value is “Four” and not “Two”. I selected “Two” in the first ComboBox, which was the ignored change. The first ComboBox is now unsynchronized with the view model. If you change the selection again, both ComboBoxes have the correct value. The problem is only with changes ignored by the view model.

Let’s create a new type derived from ComboBox to fix this problem.

namespace JamesKovacs.MvvmComboBox {
    public class ComboBox : System.Windows.Controls.ComboBox {
        protected override void OnSelectionChanged(SelectionChangedEventArgs e) {
            base.OnSelectionChanged(e);
            var binding = GetBindingExpression(SelectedItemProperty);
            if(binding != null) {
                binding.UpdateTarget();
            }
        }
    }
}

I perform the normal OnSelectionChanged event and then update the ComboBox’s SelectedItemProperty from the bound ViewModel if a binding exists. This ensures that if the view model ignores changes or modifies the selection in some way, the ComboBox displays the correct value. Minor note: I am defining a derived ComboBox in my own namespace, which is also called ComboBox. I do this so that in my XAML, I can apply the fix by prepending <ComboBox/> with my namespace <mvvm:ComboBox/>. With this fix in place, my MVVM ComboBox remains synchronized with its view model.

image

In most cases, MVVM model binding dramatically simplifies your WPF code. Unfortunately there are some cases where bugs in the framework prevent it from working properly. Fortunately in many cases you can work around these limitations by simply deriving your own custom control from the one supplied with WPF to fix these problems.

For those of you who want to play around with the code, you can find it here. Happy coding!

ADDENDUM: As noted by Michael L. Perry in this comment, WPF behaviours can also be used to inject code without subclassing ComboBox. The code sample now includes his behaviour code in addition to the subclassing option. Also to note is that a bug in .NET 4.0 prevents the fix from working. The ComboBox (regulard, subclassed, or behavioured) becomes unsynchronized from the view model. The subclassing code works correctly in .NET 3.5. If there are any WPF gurus out there who can understand why it works in .NET 3.5, but not .NET 4.0, I would love to hear an explanation.

imageSystem.Type and XML are the nuts and gum of the development world. You can stuff a System.Type into an XML file, but it leaves a bad taste in your mouth. Sometimes you don’t have much choice. For example:

  • Custom configuration sections in App.config/Web.config
  • Handlers and modules in Web.config
  • ProxyFactoryFactory, 2nd-level cache provider, database dialect, and other pieces of configuration in hibernate.cfg.xml*
  • XML-based IoC configuration**

* NHibernate Loquacious configuration is now a better option for configuring NHibernate IMHO and I use it in all my new apps rather than hibernate.cfg.xml.

** For IoC containers, convention-over-configuration is a better choice followed by code-based configuration. I use XML-based configuration only as a last resort, but it can sometimes be useful for configurable overrides.

When you do need to encode a System.Type into a XML file, JetBrains ReSharper makes your life a lot easier. (This is a little-known feature of ReSharper shown to me by Ilya “Orangy” Ryzhenkov, ReSharper Product Manager.) I decided to create a completely silly, contrived example where we need to display a list of hot peppers and their Scoville heat units and the information is stored in App.config. (Yes, I know. A database or flat file would be a better place. I told you that it was a contrived example.) I have created a PeppersConfigurationSection class that is defines the <peppers> configuration section. I need to specify the type name in the <configurationSections> where it says <INSERT_TYPE_NAME_HERE>

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="peppers" type="<INSERT_TYPE_NAME_HERE>" />
  </configSections>
  <peppers>
    <pepper name="Crazy Jerry's Brain Damage" scovilles="11000" type="sauce"/>
    <!-- more peppers -->
  </peppers>
</configuration>

Rather than typing out the namespace-qualified type name, I simply type PCS for PeppersConfigurationSection and press ReSharper’s Import Symbol Completion (IDEA: CTRL-ALT-Space; VS: ALT-SHIFT-Space).

Import Type Completion

You can see the normal ReSharper completion pop-up appear. Selecting the first one, I get:

Type Completed

This is fine and dandy if the custom configuration section is defined in your project, but what if you need to specify the assembly name too? ReSharper once again comes to our rescue with a Quick Fix (ALT-Enter).

Add module qualification

Selecting the Add module qualitication Quick Fix and we end up with this. (I added linebreaks between the parts of the fully qualified type name for ease of readability in the screenshot.)

ImportTypeCompletion4

Add module qualification is even handier if the assembly has a public key token as those are a hassle to look up. Once again, ReSharper does the hard work of inserting the type name – I only typed NVSH CTRL-ALT-Space – and then the quick fix to get the qualification with assembly name, version, culture, and public key token:

ImportTypeCompletion5

I hope this little ReSharper gem makes your coding lives just a little bit easier…

N.B. ReSharper 5.1 and 6.0 EAP (up to at least build 2136) has a bug that causes Import Symbol Completion to fail for files named Web.config in a ASP.NET project. If you rename Web.config to Foo.config – no other changes necessary – you can use Import Symbol Completion. Just remember to rename the file back to Web.config when you’re done. Another option is to copy Web.config to another project type (Console and Class Library both work), make your changes, and then copy back. I have reported the issue to JetBrains here and the team is working on a fix.

[Code for this article is available on GitHub here.]

Nothing gets an OO zealot hot under the collar the way the term polymorphism does. You probably have three questions right now… What does polymorphism have to do with object-relational mapping? How does it relate to NHibernate? And why should I care?

An ORM that supports polymorphic loading allows us to request one type of object, but potentially get an object of a derived type back. As an example, let’s say we have the following simple inheritance hierarchy in our application:

Animal Inheritance Hierarchy

We can query for an Animal, but receive back an instance of Dog or Cat instead.

var dog = session.Get<Animal>(dogId);

NHibernate has supported this type of polymorphic loading behaviour for awhile, but the base class (or interface) had to be mapped. If it wasn’t, polymorphic loading would only work when querying with Criteria or LINQ. The following works for both NH 2.1.2 and NH3 regardless of whether the Animal base class is mapped or not.

var animal = session.CreateCriteria<Animal>()
                    .Add(Restrictions.IdEq(dogId))
                    .UniqueResult<Animal>();

// N.B. Use session.Linq<Animal>() in NH2.1.2
var query = from a in session.Query<Animal>()
            where a.Id == dogId
            select a;
var animal = query.Single();

In NHibernate 2.1.2 and earlier, ISession.Get<T>(id) or ISession.Load<T>(id) would fail if T was an unmapped base class or interface. With NHibernate 3, these methods now work regardless of whether T is mapped or not.*

// Works in NH3; works in NH2.1.2 only if Animal is mapped
// In the sample code, works in NH3 for both Animal and UnmappedAnimal base classes
// In NH2.1.2 and before, works for Animal (mapped), but not UnmappedAnimal
var dog = session.Get<Animal>(dogId);
var cat = session.Load<Animal>(catId);

ASIDE: ISession.Get(id) returns null when the entity doesn’t exist in the database, whereas ISession.Load(id) throws an exception. Generally ISession.Load(id) is preferred if you know the entity should exist as NHibernate can return a proxy object that delays hitting the database until the last possible moment. ISession.Get(id) requires querying the database immediately because there is no way to return an object (e.g. a proxy), but later change it to null when accessed.

In NHibernate 3, polymorphic loading works for Criteria, LINQ, and Get/Load. It has not been implemented for HQL. (If you want/need this feature, the NHibernate team is always willing to accept a feature request with patch.) HQL in NH3 supports polymorphic loading if the queried class is imported via <import class=”UnmappedClass”/> in a hbm.xml file.

// Criteria works in NH2.1.2 and NH3
var animal = session.CreateCriteria<UnmappedAnimal>()
                    .Add(Restrictions.IdEq(dogId))
                    .UniqueResult<UnmappedAnimal>());

// LINQ works in NH2.1.2 and NH3 (NH2.1.2 uses session.Linq<T>())
var query = from a in session.Query<UnmappedAnimal>()
            where a.Id == dogId
            select a;
var animal = query.Single();

// Get/Load works in NH3, but fails in NH2.1.2 and earlier
var animal = session.Get<UnmappedAnimal>(dogId);

// HQL works for NH3 if UnmappedAnimal is imported, but fails for NH2.1.2
var animal = session.CreateQuery("from a in UnmappedAnimal where a.id = :id")
                    .SetParameter("id", dogId)
                    .UniqueResult<UnmappedAnimal>());

* I should note one restriction on the generic parameter T when calling ISession.Get<T>(id) and ISession.Load<T>(). Polymorphic loading only works if there is a unique persister for T. Otherwise NHibernate throws a HibernateException, “Ambiguous persister for [T] implemented by more than one hierarchy”. What does this mean? Let’s say you have an unmapped abstract base class, such as Entity. (Entity is a class defined in our application, which includes properties common across all persistent entities, such as primary key, audit fields, and similar. It is not required by NHibernate, but often useful for extracting common domain code.) Consider the following contrived example:

Contrived Inheritance Hierarchy

Note that the Animal inheritance hierarchy is mapped and so is Customer. If we try to execute the following code:

var id = 42;
var entity = session.Get<Entity>(id);

We will get a HibernateException as mentioned above. We are asking NHibernate to load an Entity with an id of 42. But primary keys are only unique within a mapped inheritance hierarchy. So there could be a Cat (or Dog) with id of 42 and a Customer with id of 42! So NHibernate fails with a HibernateException since it has no way of returning a list of objects from Get/Load. If you really want to query across inheritance hierarchies, you can do so with Critera or LINQ where you return a list of objects. The following code will work:

var id = 42;
var entities = session.CreateCriteria<Entity>()
                      .Add(Restrictions.IdEq(id))
                      .List<Entity>();

Here’s a NHibernate trick that makes for a good demo, but isn’t terribly practical in real applications… Retrieve a list of all entities in the database:

var allEntities = session.CreateCriteria<object>()
                         .List<object>();

Happy coding!

UPDATE: Fabio Maulo, NH project lead, pointed out to me that HQL in NHibernate 3 can load unmapped classes so long as you make NHibernate aware of the classes via an <import class=”UnmappedAnimal”/> directive in a hbm.xml file. Thanks, Fabio.

We’ve all done it at one point or another. Our application throws an exception and we start wading through a standard Windows error dialog or a log file to examine the exception and stack trace. If you’re a ReSharper Jedi, you’ve probably copied the exception and stack trace to the clipboard and hit CTRL-SHIFT-E (IDEA) or CTRL-E, T (VS) in Visual Studio to launch ReSharper’s Stack Trace Explorer. (If you have’t, you’ll see the Stack Trace Explorer in just a second.)

Let me show you an easier way that works well on desktop or Silverlight apps. I’ll use Silverlight for demo purposes, but the same technique works with WPF and WinForms. First we need to hook up a global error handler:

public MainPage() {
    InitializeComponent();
    Application.Current.UnhandledException += HandleApplicationUnhandledException;
}

private static void HandleApplicationUnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e) {
    if(Debugger.IsAttached) {
        Clipboard.SetText(e.ExceptionObject.ToString());
    }
    e.Handled = false;
}

Please note that this is demo code and I’m simply hooking this up in the code behind. In a larger application, I would typically publish an ErrorOccurred message to my application’s message bus and register a listener that would contain the code in HandleApplicationUnhandledException.

Notice that I’m checking whether a debugger is attached. If so, I place the contents of the System.Exception (or derived exception) on the clipboard. (Clipboard is in the System.Windows namespace for Silverlight and WPF apps, but there is an identically-named class in System.Windows.Forms.) The reason that I’m checking whether a debugger is attached is so that end-users don’t get the clipboards spammed with exception text. You could conditionally compile the code so that production builds don’t contain it, but personally I like having the code in production too. It means that I can grab an old build, attach a debugger, and get the same exceptions that the end users are getting.

Now that the exception and stack trace is on the clipboard, I jump over to Visual Studio and press CTRL-SHIFT-E (IDEA) or CTRL-E, T (VS). I am immediately presented with ReSharper’s Stack Trace Explorer as ReSharper is smart enough to grab the current clipboard contents to display:

StackTraceExplorer

The advantage here is fictionless debugging as you no longer have to find, select, and copy the exception and stack trace to the clipboard. It’s there for you automatically. As soon as you hit an exception, simply jump to Visual Studio and press CTRL-SHIFT-E (IDEA) or CTRL-E, T (VS) and you’re ready to find the problem. Also note that all the method names in the ReSharper’s Stack Trace Explorer are hot links to the appropriate code file allowing for easy navigation of your code base, the .NET Framework, and third-party libraries.

One quick note regarding Silverlight… Many modern browsers (e.g. FF4, IE8+, Chrome, …) will run Silverlight in a separate process. So even when you launch with debugging (F5), you’ll be attached to the browser process itself and not the child process that is hosting Silverlight. To correct this, simply go to Debug… Attach to Process… and find the hosting process where the type is Silverlight. (For FireFox 4, the hosting process is called plugin-container.exe. For IE8+ and Chrome, the hosting process is called iexplore.exe or chrome.exe, respectively. Just look for the one hosting Silverlight as noted under the “Type” column.)

AttachToProcess

Happy Debugging!

[Code for this article is available on GitHub here.]

In this post, we’ll examine the ways that NHibernate supports the DateTime-related data types, including some new features introduced in NHibernate 2 and 3. Here is a quick summary for the impatient.

DbType .NET SQL Type
DateTime System.DateTime datetime
LocalDateTime System.DateTime datetime
UtcDateTime System.DateTime datetime
DateTimeOffset System.DateTimeOffset datetimeoffset
DateTime2 System.DateTime datetime2
Date System.DateTime date
Time System.DateTime time
TimeAsTimeSpan System.TimeSpan time
TimeSpan System.TimeSpan bigint (int64)

Local/UTC

Let’s take a look at a few DateTime-related problems that developers have run into in the past…

public class DateTimeEntity {
    public DateTimeEntity() {
        CreationTime = DateTime.Now;
    }

    public virtual Guid Id { get; private set; }
    public virtual DateTime CreationTime { get; set; }
}

Note that CreationTime is initialized using DateTime.Now. The corresponding mapping file would be:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"

namespace="Nh3Hacking"

assembly="Nh3Hacking"> <class name="DateTimeEntity"> <id name="Id"> <generator class="guid.comb" /> </id> <property name="CreationTime"/> </class> </hibernate-mapping>

If we create an instance of our DateTimeEntity and reload it, we get:

Original entity:
Id: 09bead07-5a05-4459-a108-9e7501204918
        CreationTime: 2011-01-24 5:29:36 PM (Local)
Reloaded entity:
Id: 09bead07-5a05-4459-a108-9e7501204918
        CreationTime: 2011-01-24 5:29:36 PM (Unspecified)

Note that I am outputting both CreationTime.ToString() and CreationTime.Kind. DateTime.Kind returns a DateTimeKind (surprising, huh?), which indicates whether this DateTime represents Local time or UTC time. We initialized the value with DateTime.Now, which is the local time. (If we wanted UTC time, we would use DateTime.UtcNow.) When the object is reloaded, the DateTimeKind is Unspecified. This is because the database does not store whether the DateTime value is Local or UTC. NHibernate has no way of knowing which one it is, hence Unspecified.

NHibernate 3 includes two new DbTypes that allow us to resolve this ambiguity. In our mapping file, we can write:

<property name="CreationTimeAsLocalDateTime" type="LocalDateTime"/>
<property name="CreationTimeAsUtcDateTime" type="UtcDateTime"/>

We are explicitly telling NHibernate whether the database stores Local or UTC times.

Original entity:
Id: 09bead07-5a05-4459-a108-9e7501204918
        CreationTimeAsDateTime: 2011-01-24 5:29:36 PM (Local)
        CreationTimeAsLocalDateTime: 2011-01-24 5:29:36 PM (Local)
        CreationTimeAsUtcDateTime: 2011-01-25 12:29:36 AM (Utc)
Reloaded entity:
Id: 09bead07-5a05-4459-a108-9e7501204918
        CreationTimeAsDateTime: 2011-01-24 5:29:36 PM (Unspecified)
        CreationTimeAsLocalDateTime: 2011-01-24 5:29:36 PM (Local)
        CreationTimeAsUtcDateTime: 2011-01-25 12:29:36 AM (Utc)

This is strictly metadata and it is up to the developer to ensure that the proper DateTime is present in the property/field. For instance, if I initialize the entity as follows:

public DateTimeEntity() {
    CreationTimeAsDateTime = DateTime.Now;
    CreationTimeAsLocalDateTime = DateTime.UtcNow;
    CreationTimeAsUtcDateTime = DateTime.Now;
}

Note that the LocalDateTime property contains a UTC DateTime and the UTC property contains a Local DateTime. The results are:

Original entity:
Id: 4579d245-46f3-4c3f-893b-9e750124a90b
        CreationTimeAsDateTime: 2011-01-24 5:45:32 PM (Local)
        CreationTimeAsLocalDateTime: 2011-01-25 12:45:32 AM (Utc)
        CreationTimeAsUtcDateTime: 2011-01-24 5:45:32 PM (Local)
Reloaded entity:
Id: 4579d245-46f3-4c3f-893b-9e750124a90b
        CreationTimeAsDateTime: 2011-01-24 5:45:32 PM (Unspecified)
        CreationTimeAsLocalDateTime: 2011-01-25 12:45:32 AM (Local)
        CreationTimeAsUtcDateTime: 2011-01-24 5:45:32 PM (Utc)

Notice that NHibernate did not perform any conversions or throw an exception when saving/loading a DateTime value with the wrong DateTimeKind. (It could be argued that NHibernate should throw an exception when asked to save a Local DateTime and the property is mapped as a UtcDateTime.) It is up to the developer to ensure that the proper kind of DateTime is in the appropriate field/property.

System.DateTimeOffset

One problem that LocalDateTime and UtcDateTime does not solve is the offset problem. If you have a DateTime and its Kind is Local, all you know is that it is a Local DateTime. You do not know if that Local DateTime is Mountain (MST), Eastern (EST), Pacific (PST), etc. You do not know whether it has been corrected for daylight savings time. All you know is that it is a Local DateTime. You have to assume that the local time is based on the time zone of the current computer. Although this is often a reasonable assumption, it’s not always. (Consider for example that you’re collecting log files from a distributed system and servers reside in multiple time zones.) The problem is that System.DateTime class does not contain a place to record the timezone offset. Microsoft solved this problem starting in .NET 3.5 by introducing the System.DateTimeOffset class. It looks a lot like System.DateTime, but does include the timezone offset rather than the DateTimeKind. So we can just use System.DateTimeOffset in our applications rather than System.DateTime.

Except… Date/time types in SQL databases do not have anywhere to store the timezone offset. The notable exception is SQL Server 2008, which introduced the datetimeoffset type. NHibernate 2 introduced support for System.DateTimeOffset, but only for SQL Server 2008 onwards. (If you’re using SQL Server 2005 or earlier or another database server, you’ll have to implement your own IUserType to store System.DateTimeOffset in two separate columns – one for the DateTime and the other for the timezone offset.) The additional code in DateTimeEntity.cs looks like this:

public virtual DateTimeOffset CreationTimeAsDateTimeOffset { get; set; }

The mapping file just needs the new property added:

<property name="CreationTimeAsDateTimeOffset"/>

Note that I don’t need to specify the type in the mapping as NHibernate can infer it from the property type in DateTimeEntity. The resulting output is:

Original entity:
Id: 95aa6c15-86f5-4398-aa9e-9e7600ae4580
        CreationTimeAsDateTime: 2011-01-25 10:34:30 AM (Local)
        CreationTimeAsLocalDateTime: 2011-01-25 10:34:30 AM (Local)
        CreationTimeAsUtcDateTime: 2011-01-25 5:34:30 PM (Utc)
        CreationTimeAsDateTimeOffset: 2011-01-25 10:34:30 AM -07:00
Reloaded entity:
Id: 95aa6c15-86f5-4398-aa9e-9e7600ae4580
        CreationTimeAsDateTime: 2011-01-25 10:34:30 AM (Unspecified)
        CreationTimeAsLocalDateTime: 2011-01-25 10:34:30 AM (Local)
        CreationTimeAsUtcDateTime: 2011-01-25 5:34:30 PM (Utc)
        CreationTimeAsDateTimeOffset: 2011-01-25 10:34:30 AM -07:00

Support for DateTime2, Date, and Time

Let’s look at some C# and the corresponding mapping file for these types:

public virtual DateTime CreationTimeAsDateTime2 { get; set; }
public virtual DateTime CreationTimeAsDate { get; set; }
public virtual DateTime CreationTimeAsTime { get; set; }
public virtual TimeSpan CreationTimeAsTimeAsTimeSpan { get; set; }
public virtual TimeSpan CreationTimeAsTimeSpan { get; set; }

Modifications to the hbm.xml:

<property name="CreationTimeAsDateTime2" type="DateTime2"/>
<property name="CreationTimeAsDate" type="Date"/>
<property name="CreationTimeAsTime" type="Time"/>
<property name="CreationTimeAsTimeAsTimeSpan" type="TimeAsTimeSpan"/>
<property name="CreationTimeAsTimeSpan"/>

We’ll examine each of these in turn…

DbType.DateTime2 is a higher precision, wider range version of DbType.DateTime. DbType.DateTime maps to the datetime (or smalldatetime) SQL type, which has a range of 1753-01-01 to 9999-12-31. DbType.DateTime2 maps to the datetime2 SQL type, which has a range of 0001-01-01 to 9999-12-31. (Precision can be as high as 1/10 of a microsecond with a datetime2(7).) One of the niceties of DateTime2 is that an uninitialized DateTime struct (which has a value of 0001-01-01 12:00:00 AM (Unspecified)) does not cause a SqlTypeException with a SqlDateTime underflow.

DbType.Date does just what it advertises. It represents a Date without a Time component. It is stored in the database as only a date. .NET does not have a Date type and NHibernate represents it via a DateTime with the time portion set to 12:00:00 AM. I personally prefer to define my own Date class, which has no time component, and create an IUserType to handle the mapping. My custom Date class can handle the time truncation and provide a more natural programing model for my domain, but that’s a post for another day.

Time-related DbTypes stores just the time, but no date. In .NET, there is no Time class and so NHibernate uses a DateTime with the date component set to 1753-01-01, the minimum value for a SQL datetime or a System.TimeSpan – depending on the DbType that we choose. DbType.Time stores a System.DateTime in a time SQL type. DbType.TimeAsTimeSpan stores a System.TimeSpan as a time SQL type. DbType.TimeSpan stores a Syste.TimeSpan as a 64-bit integer (bigint) SQL type. As I mentioned for DbType.Date, I am more inclined to write my own Time class and custom IUserType to achieve a better programming model than relying on the .NET constructs of System.DateTime and System.TimeSpan. (I typically use System.DateTime or System.TimeSpan as a field in my custom Date or Time class for storing the data, but provide my own API for consistently working with the data.)

WARNING: Not all databases support all date/time SQL types. So before choosing .NET and SQL types for your entities, make sure that they’re available in all databases that you plan to support.

Now we’ll take a look at these date/time types in action:

Original entity:
Id: 6b2fb9ff-8036-4c17-b9ef-9e7600bf37e3
        CreationTimeAsDateTime: 2011-01-25 11:36:12 AM (Local)
        CreationTimeAsLocalDateTime: 2011-01-25 11:36:12 AM (Local)
        CreationTimeAsUtcDateTime: 2011-01-25 6:36:12 PM (Utc)
        CreationTimeAsDateTimeOffset: 2011-01-25 11:36:12 AM -07:00
        CreationTimeAsDateTime2: 2011-01-25 11:36:12 AM (Local)
        CreationTimeAsDate: 2011-01-25 11:36:12 AM (Local)
        CreationTimeAsTime: 2011-01-25 11:36:12 AM (Local)
        CreationTimeAsTimeAsTimeSpan: 11:36:12.2688265
        CreationTimeAsTimeSpan: 11:36:12.2688265
Reloaded entity:
Id: 6b2fb9ff-8036-4c17-b9ef-9e7600bf37e3
        CreationTimeAsDateTime: 2011-01-25 11:36:12 AM (Unspecified)
        CreationTimeAsLocalDateTime: 2011-01-25 11:36:12 AM (Local)
        CreationTimeAsUtcDateTime: 2011-01-25 6:36:12 PM (Utc)
        CreationTimeAsDateTimeOffset: 2011-01-25 11:36:12 AM -07:00
        CreationTimeAsDateTime2: 2011-01-25 11:36:12 AM (Unspecified)
        CreationTimeAsDate: 2011-01-25 12:00:00 AM (Unspecified)
        CreationTimeAsTime: 1753-01-01 11:36:12 AM (Unspecified)
        CreationTimeAsTimeAsTimeSpan: 11:36:12.2700000
        CreationTimeAsTimeSpan: 11:36:12.2688265

Summary

As you have seen, NHibernate has a wide variety of options for mapping date/time-related types to and from the database. The right choice is highly dependent on your application and database server. I hope that this post has given you a few more tricks up your sleeve for effectively mapping date/time-related types using NHibernate.

[Code for this article is available on GitHub here.]

One of the new features in NHibernate 3 is the addition of a fluent API for configuring NHibernate through code. Fluent NHibernate has provided a fluent configuration API for awhile, but now we have an option built into NHibernate itself. (Personally I prefer the new Loquacious API to Fluent NHibernate’s configuration API as I find Loquacious more discoverable. Given that Fluent NHibernate is built on top of NHibernate, you can always use Loquacious with Fluent NHibernate too. N.B. I still really like Fluent NHibernate’s ClassMap<T>, automapping capabilities, and PersistenceSpecification<T>. So don’t take my preference regarding fluent configuration as a denouncement of Fluent NHibernate.)

The fluent configuration API built into NHibernate is called Loquacious configuration and exists as a set of extensions methods on NHibernate.Cfg.Configuration. You can access these extension methods by importing in the NHibernate.Cfg.Loquacious namespace.

var cfg = new Configuration();
cfg.Proxy(p => p.ProxyFactoryFactory<ProxyFactoryFactory>())
   .DataBaseIntegration(db => {
                            db.ConnectionStringName = "scratch";
                            db.Dialect<MsSql2008Dialect>();
                            db.BatchSize = 500;
                        })
   .AddAssembly(typeof(Blog).Assembly)
   .SessionFactory().GenerateStatistics();

On the second line, we configure the ProxyFactoryFactory, which is responsible for generating the proxies needed for lazy loading. The ProxyFactoryFactory type parameter (stuff between the <>) is in the NHibernate.ByteCode.Castle namespace. (I have a reference to the NHibernate.ByteCode.Castle assembly too.) So we’re using Castle to generate our proxies. We could also use LinFu or Spring.

Setting db.ConnectionStringName causes NHibernate to read the connection string from the <connectionStrings/> config section of the [App|Web].config. This keeps your connection strings in an easily managed location without being baked into your code. You can perform the same trick in XML-based configuration by using the connection.connection_string_name property instead of the more commonly used connection.connection_string.

Configuring BatchSize turns on update batching in databases, which support it. (Support is limited to SqlClient and OracleDataClient currently and relies on features of these drivers.) Updating batching allows NHibernate to group together multiple, related INSERT, UPDATE, or DELETE statements in a single round-trip to the database. This setting isn’t strictly necessary, but can give you a nice performance boost with DML statements. The value of 500 represents the maximum number of DML statements in one batch. The choice of 500 is arbitrary and should be tuned for your application.

The assembly that we are adding is the one that contains our hbm.xml files as embedded resources. This allows NHibernate to find and parse our mapping metadata. If you have your metadata located in multiple files, you can call cfg.AddAssembly() multiple times.

The last call, cfg.SessionFactory().GenerateStatistics(), causes NHibernate to output additional information about entities, collections, connections, transactions, sessions, second-level cache, and more. Although not required, it does provide additional useful information about NHibernate’s performance.

Notice that there is no need to call cfg.Configure(). cfg.Configure() is used to read in configuration values from [App|Web].config (from the hibernate-configuration config section) or from hibernate.cfg.xml. If we’ve not using XML configuration, cfg.Configure() is not required.

Loquacious and XML-based configuration are not mutually exclusive. We can combine the two techniques to allow overrides or provide default values – it all comes down to the order of the Loquacious configuration code and the call to cfg.Configure().

var cfg = new Configuration();
cfg.Configure();
cfg.Proxy(p => p.ProxyFactoryFactory<ProxyFactoryFactory>())
   .SessionFactory().GenerateStatistics();

Note the cfg.Configure() on the second line. We read in the standard XML-based configuration and then force the use of a particular ProxyFactoryFactory and generation of statistics via Loquacious configuration.

If instead we make the call to cfg.Configure() after the Loquacious configuration, the Loquacious configuration provides default values, but we can override any and all values using XML-based configuration.

var cfg = new Configuration();
cfg.Proxy(p => p.ProxyFactoryFactory<ProxyFactoryFactory>())
   .DataBaseIntegration(db => {
                            db.ConnectionStringName = "scratch";
                            db.Dialect<MsSql2008Dialect>();
                            db.BatchSize = 500;
                        })
   .AddAssembly(typeof(Blog).Assembly)
   .SessionFactory().GenerateStatistics();
cfg.Configure();

You can always mix and match the techniques by doing some Loquacious configuration before and som after the call to cfg.Configure().

WARNING: If you call cfg.Configure(), you need to have <hibernate-configuration/> in your [App|Web].config or a hibernate.cfg.xml file. If you don’t, you’ll throw a HibernateConfigException. They can contain an empty root element, but it needs to be there. Another option would be to check whether File.Exists(‘hibernate.cfg.xml’) before calling cfg.Configure().

So there you have it. The new Loquacious configuration API in NHibernate 3. This introduction was not meant as a definitive reference, but as a jumping off point. I would recommend that you explore other extension methods in the NHibernate.Cfg.Loquacious namespace as they provide the means to configure the 2nd-leve cache, current session context, custom LINQ functions, and more. Anything you can do in XML-based configuration can now be accomplished with Loquacious or the existing methods on NHibernate.Cfg.Configuration. So get out there and start coding – XML is now optional…

Darth VaderThanks to everyone who came out to my session on Convention-over-Configuration on the Web at TechDays Calgary 2010. I enjoyed sharing my ideas about convention-over-configuration and how it can simplify software development. You expend some serious brain power over figuring out how to enable your application-specific conventions, but everything after that flows easily and without repetition. You end up doing more with less code. During the talk, I demonstrated how frameworks like Fluent NHibernate, AutoMapper, Castle Windsor, ASP.NET MVC, and jQuery support this style of development. (Links below.) I only scratched the surface though. With a bit of creative thinking, you can use these techniques in your own code to reduce duplication and increase flexibility.

You can grab a zip of the source code directly from here or view the source tree on GitHub here.

DevTeachDevTeach is heading back to Toronto in a few weeks (March 8-12, 2010)and you’ll get a bigger dose of awesome than ever before. We’ve got a fantastic line-up of top-notch, internationally renowned speakers. 6 tracks covering Agile, Web, Windows, Silverlight, Architecture, and SharePoint. A metric ton of sessions. (I’m both the Agile and Web Track Chairs and am really excited about the speakers and sessions for each.)

ee402630.VisualStudio_lgMicrosoft Canada is a platinum sponsor and every attendee receives a full copy of Visual Studio Professional with MSDN Premium. (N.B. Conference registration costs less than this subscription alone!)

imageAnd if you can’t get enough of that Sugar Crisp James Kovacs,  I’ll be there in full force with two sessions and a one-day post-con on agile development.

Convention-over-Configuration in an Agile World

As developers, we spend an inordinate amount of time writing “glue code”. We write code to transform database rows to domain objects… domain objects to view-models or DTOs… We write code to configure inversion of control containers and wire dependencies together. We write code to style our UIs and respond to UI events. Wouldn’t it be nice if this could happen automagically for us? This session will look at using convention-based approaches using Fluent NHibernate and Castle Windsor to reduce the amount of repetitive code and accelerate application development.

Convention-over-Configuration in a Web World

As developers, we spend an inordinate amount of time writing “glue code”. We write code to transform database rows to domain objects… domain objects to view-models or DTOs… We write code to configure inversion of control containers and wire dependencies together. We write code to style our UIs and respond to UI events. Wouldn’t it be nice if this could happen automagically for us? This session will look at using convention-based approaches using AutoMapper and jQuery to reduce the amount of repetitive code and accelerate application development.

Agile Development with IoC and ORM (Post-Con)

As developers we now have powerful tools in our toolbox, such inversion of control containers and object-relational mappers. But how can we use these tools to rapidly build maintainable and flexible applications? In this pre-con, we will look at advanced techniques such as convention-over-configuration in IoC containers and automapping ORMs to quickly build applications that can evolve over time. We will use test-driven development (TDD) to design and evolve a complete working application with supporting infrastructure during this one-day workshop.

Hope to see you in Toronto!

Sand Zen Garden A few months back, I announced that I was doing a series of articles for MSDN Magazine on improving a “classic” ASP.NET application with modern tooling and frameworks. As an application, I chose ScrewTurn Wiki 3.0 to use as my example throughout. The first article, Extreme ASP.NET Makeover – Getting Your House in Order, went live a few days ago. The article is purposefully a different format for MSDN Magazine than “traditional” articles in that it incorporates short screencasts where appropriate rather than just code snippets and pictures. (Code snippets and pictures are included too, though!) I tried to make the screencasts an integral part of the narrative where actually showing something was easier than text, pictures, or code. I would love to hear your feedback on the format and content.

Nitpickers Corner: In the series, I use MSBuild as the build tool. Yes, I wrote my own PowerShell-based build tool, psake. Yes, I use NAnt on many of my projects for clients. (They’re already using NAnt and PowerShell is a new skillset for them.) So why MSBuild for the series? Because it is installed by default with .NET 2.0 and above. Not my first choice, but a pragmatic choice for a series focused on improving what you have.