zaterdag 3 november 2007

Castle Windsor and ActiveRecord

I sometimes read blogposts where people mention Castle Windsor and Castle's ActiveRecord, so I decided to have a little peek at these two projects.

Castle Windsor is an IoC container and ActiveRecord is an implementation of the Active Record pattern which internally uses NHibernate.
These projects look very interesting, and I'd like to make use of them in a little hobby-project before using it in a real-world project

Is there anybody who has used one (or both) of these projects in a real world scenario and who wants to share his (or her) findings ?

woensdag 24 oktober 2007

New debugging experience in VS.NET 2008

As I was reading a bit on Bart De Smet's weblog today, I came accros an interesting post where Bart talks about a new 'debugging experience in VS.NET 2008.

It seems that Microsoft will release the source code for the .NET Framework libraries, and that there will be an integrated debugging support in VS.NET 2008.
This means: when debugging your code, it should be possible to 'step into' the code of the .NET framework classes.
I think this is great!

I've also read another interesting thing on Bart's weblog: Bart will be working in the MS HQ's in Redmond, where he'll work on WPF. That must be a great job, and I'd like to wish Bart a lot of succes!

donderdag 18 oktober 2007

MSDN RampUp

Microsoft has set up a programme in which you can take part to gain new or refresh your existing .NET development skills.
This programme is called 'MSDN Ramp Up'. It is an online course with a lot of course material and online virtual labs.

The nice thing about this Ramp Up programme, is that Microsoft has made different 'tracks', which are tailored to the existing experience and knowledge of the student.
There are four tracks available:

  • Aspiring Developer; which is suited for people who have no prior programming experience, but want to learn programming with MS technology

  • Java Developer; this track is for Java developers who want to gain knowledge about the .NET framework and want to learn programming in C#

  • MS Visual Basic 6.0 developer; lets existing VB 6 developers become proficient in .NET and VB.NET 2005

  • MS VS.NET 2002/2003 developer; introduces the .NET 1.x developer with the improvements and changes in the .NET 2.0 framework

If you want to learn more about this programme, or want to take part in it, then visit this website.

vrijdag 28 september 2007

MS LEAP Programme, yet another rant.

A while ago, I received an e-mail with an invitation to take part in the MS LEAP programme.

This looked very interesting, so I asked my employer if I could take that course and if my employer could help me bear the costs.
A few days later, I received the answer that I could and that they (the company where I work) would bear the majority of the cost. \o/

Now, today, I wanted to subscribe but unfortunately, the program is already fully booked. :(

The ranting doesn't stop. :(

donderdag 27 september 2007

Auto-Formatting in VS.NET 2005 does not work anymore

After a harddisk-crash, I had to reinstall Visual Studio.NET 2005.
As I started programming again after it was re-installed, I noticed that the 'auto-formatting' function of VS.NET didn't work anymore ...

This is very strange, and very annoying once you're used to it. I've verified my options, and they're set the way I want too.
The options:

  • Automatically format completed statement on;
  • Automatically format completed block on }

are enabled. However, when I type a ; or a }, the code is not being formatted at all...
When I use the shortcut 'Ctrl + E, D (format document)', my current document is formatted.

I've no idea why this doesn't work anymore. I've just made a fresh install of VS.NET.
Is there anybody who has experienced this 'annoyance' as well, and if so, how did you fix it ?
In other words: if there's anybody out there who knows how to fix it, please let me know. :)

maandag 13 augustus 2007

Cleaning a Keyboard

My keyboard is about 5 years old, and it has been used extensively. During these years, it has become more and more filthy.
Now, I thought the time has come to do something about it. Basically, I had two options:

  • Buy a new keyboard
  • Clean my keyboard

I thought the second option was more of a challenge then just buying a new one.
So, this is what I did.

To give you an idea of how filthy my keyboard actually was, I've made a picture of it:

filthy keyboard

After I took a picture of the layout of my keyboard, I removed all keys from the board. You can imagine that the picture I've taken comes in quite handy when I wanted to place the keys back.

removing keys from keyboard

I've put all the keys in a bucket of water, and cleaned them.
After removing all the keys, the keyboard looked like this:

stripped keyboard

Hmm, this contains a lot of filth as well. I made good use of the vacuum-cleaner to remove most of it.
Then, when all the cleaned keys were dry again, I could put all the keys back to where they belong. The result: a clean keyboard:

clean keyboard

It was quite some work, but, devving with a clean keyboard is much nicer then using a dirty one. ;)

woensdag 8 augustus 2007

C# 3.0: new language features

I've already written a blogpost regarding LINQ and new language features that we may expect in C# 3.0 a while ago.
Since the release of VS.NET 2008 and thereby C# 3.0 is coming closer and closer, I was planning to write an updated blogpost about the new language features in C# 3.0.

However, I've noticed that John Papa has already written an excellent article already concerning the language enhancements in .NET 3.5, so I've decided to just link to that article:

.NET 3.5 Language Enhancements
That's much easier for me, and it saves me some time. :)

zaterdag 4 augustus 2007

XSD Schema for configuration of Log4Net

A few days ago, I was playing around with log4net, the open source framework that allows you to easily log messages in an application.

Since log4net is very configurable, I wanted to have Intellisense in Visual Studio.NET when I'm editing the log4net configuration.
Therefore, I need a schema definition for the log4net XML configuration file so that I can set up the Intellisense for the log4net configuration as I did here for NHibernate.

Unfortunately, it seems that the source of log4net doesn't contain such an XSD.
So, before I take the time and effort to create such an XSD, I wonder if anyone has already made such an XSD for log4net and is willing to share it. :)

vrijdag 27 juli 2007

NHibernate & MS Access: problems with autonumber fields

I was playing around with NHibernate and MS Access a bit the other day, and I ran into an annoying problem.

When I tried to save an object which maps to a table wich has an 'autonumber' field, I received this error:

a different object with the same identifier value was already associated with the session: 0

It looked like NHibernate was unable to retrieve the ID that has been given to the new record in the database.

So, I decided to set up log4net to see if I could find any clue in the logs about the reason for this problem.

As it turned out, it seems that NHibernate was closing the database-connection between the INSERT and the SELECT @@identity statements.

DEBUG NHibernate.SQL - INSERT INTO table ...
DEBUG NHibernate.Connection.DriverConnectionProvider - Obtaining
IDbConnection from Driver
DEBUG NHibernate.Impl.BatcherImpl - Closed IDbCommand, open IDbCommands: 0
DEBUG NHibernate.Impl.ConnectionManager - aggressively releasing
database connection
DEBUG NHibernate.Connection.ConnectionProvider - Closing connection
DEBUG NHibernate.Impl.BatcherImpl - Opened new IDbCommand, open IDbCommands: 1
DEBUG NHibernate.Impl.BatcherImpl - Building an IDbCommand object for
the SqlString: select @@identity
DEBUG NHibernate.SQL - select @@identity

After some research in the Hibernate documentation and on the Internet, I discovered that this is caused by the 'connection release mode'.

The default connection release mode seems to release the connection after each SQL statement, so obviously, Access is not able to determine the correct ID of the last inserted record, since the select @@identity command must be executed on the same connection as its related INSERT statement.

Now that we know what caused this problem, it is easy to fix it: just make sure that you do not use the default connection release mode when using NHibernate with MS Access.

To do so, you should specify the connection release mode in your NHibernate configuration file like this:

<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="hibernate.connection.release_mode">on_close</property>
</session-factory>
</hibernate-configuration>

More information regarding the different options / settings for the connection-release mode can be found here.

woensdag 18 juli 2007

Counting in SQL Server: SELECT COUNT(*) != SELECT COUNT(columnname)

Today, I've learned something new; or rather, I was being pointed out something that I didn't know about:
It seems that, doing a SELECT COUNT(columnname) does not always give you the same results as doing a SELECT COUNT(*). As it was pointed out to me, doing a SELECT COUNT(columnname) returns the number of rows in the resultset in where the value of the field in 'columnname' is NOT NULL.

This means that, given the following set of data:

idname
1Name1
2NULL
3Anothername

performing this statement:

SELECT COUNT(*) FROM table
gives us 3 as a result, while doing this:
SELECT COUNT(name) FROM table
returns 2 as result.

I really was ignorant to this behaviour, as I do (or did), most of the time a SELECT COUNT(1) FROM table instead, since I thought that this was the most performant option, but this also seems to be not true in some circumstances;
doing a SELECT COUNT(*) enables SQL Server to use indexes in calculating the number of results in a resultset.

For a more thourough article about this, I'd like to refer to this article on SQL Server Central.

Thanks to Peter De Boer for pointing this out

maandag 18 juni 2007

Dependency Injection versus Service Locators

When I was driving home from work, I have been thinking: when an object (entity) needs a reference to a repository for instance, to get some work done, how do you get a reference to that dependency (in this case, the repository) ?
Do you use dependency injection, or do you use a service locator ? When to choose what ? What are the advantages / disadvantages over both approaches ?

For example, suppose you have a 'Customer' class; this class has a property 'Status' which says whether the Customer is a 'Gold Customer', a 'Badly Paying Customer' or a 'Normal Customer'.
In order to determine to which 'state' a specific Customer belongs to, it might be necessary to retrieve some information out of a datastore. In this case, it could be necessary for instance to retrieve some invoice information regarding this customer.
(A Gold Customer for instance, is a Customer who has ordered for a specific amount of goods in a certain period, while a Bad Payer might be some-one who has overdue invoices).
So, a reference to an instance of IInvoiceRepository must be given to the Customer object.
The question now is, how do you give this dependency to the Customer object ?

Do you use 'Dependency Injection', and give this dependency via a constructor or a property to the Customer instance, like this:

Customer c = customerRepository.GetCustomer (5);
c.InvoiceRepository = repositoryFactory.CreateInvoiceRepository();

Or, should you leave this responsability to the Customer object ? In other words: let the Customer instance search for the correct IInvoiceRepository using a service locator. This could then be done in the Status property of the Customer class:

public CustomerStatus Status
{
get
{
IInvoiceRepository ir = DomainSettings.Instance.RepositoryLocator.GetInvoiceRepository();
...
return status;
}
}

In this case, the 'RepositoryLocator' can decide which implementation of IInvoiceRepository it has to create and return based on a value in a config file for instance.

Anyway, when do you choose for which option ? What are the advantages /disadvantages of both concepts ? In which situation do you favor the one over the other ?

I hope that some smart people can enlighten me about this matter. :)

maandag 30 april 2007

NHibernate Session Management in Domain Driven App's

As I've posted earlier, Billy McCafferty has written an excellent article on using NHibernate within ASP.NET applications.
In this article, he describes how to use the 'Open Session in View' pattern. This is perfectly useable and a very clean way of working with NHibernate in a DDD ASP.NET application, unfortunately, it is -imho- less (or not) useable in a WinForms application.
The 'Open Session in View' pattern implies that a new NHibernate ISession object is created at each request, and closed at the end of each request. (Changes are committed as well).

It is very important that the Repositories keep their hands off of Transaction Management. In other words: a repository should not start, commit or rollback a transaction. This is natural, since the repository doesn't know anything of the 'context' of the Unit of Work. Therefore, transaction managment should be a responsability of the client (the UI, the Service layer, whatever).
To achieve this, Billy stores the current ISession in the CallContext or HttpContext (he has made abstraction of which implementation is used offcourse. CallContext is used in the case of a WinForms app or a Unit-Test project, HttpContext is used in case of an ASP.NET app; see the source-code that accompagnies the article for more details).
In this way, the repositories can easily access the current ISession when they need it by just getting it out of the CallContext or HttpContext, and the ASP.NET application (the ASP.NET webpages) have access to the ISession as well, so they can start, commit and rollback the unit-of-work.
This is the ideal solution in ASP.NET, since you only need one 'ISession' on each request. At the end of the request, the Session can be closed (committed / rollbacked), so they're short-lived, and this is perfect.

However, in a WinForms application, you'll probably want more then one 'Unit of Work' at the same time, and therefore, have more then one open ISession at the same time.
An example will clarify this a bit more:

Suppose you've a WinForms application which consists of a form which lists all Customers. You can edit a customer by double-clicking it; a 'Customer-Detail' form will open up, where you can make changes to the Customer.

Now, what happens if you edit a Customer ? You'll retrieve the ISession from the CallContext, load the Customer from the DB, make some changes and confirm the changes; closing the form will close the ISession.
So far, no problem. However, what happens if you open another Customer-Detail form before you've committed the changes to the first Customer ?
What if you have 2 Customer Detail Forms open, make changes to Customer 1, save the changes and close the form. Afterwards, you want to save the changes to Customer 1... The problem now is that you've closed the ISession when you've closed the first Customer-Detail form. Customer 2 was attached to the same session which is now closed. If you want to save the changes to customer 2, you'll need an ISession, so you'll require a new ISEssion in this case. Then, NHibernate will think that Customer 2 is a new Customer, and will try to insert a new record to the DB where in fact, the existing Customer needs to be updated.

In my opinion, it is better to have a seperate Unit Of Work (ISession) for each instance of the CustomerDetail form in this case.
This implies that you should create a new ISession for each instance of the CustomerDetail form: this means that the ISession cannot be kept in the CallContext since otherwise, each form would share the same ISession.
Then... how should this be solved ? In my humble opinion, the best way to solve this is to create an ISession when an instance of a form is created, pass it to the repositories, and use it to handle the transaction(s) in the form:

public class CustomerDetailForm : Form
{
private ISession _unitOfWork;

private CustomerRepository _custRep;

private Customer _customer;

public void ShowCustomer( int customerId )
{
_unitOfWork = AppSettings.Instance.SessionFactoryObj.OpenSession();

_custRep = new CustomerRepository(_unitOfWork);

_customer = _custRep.GetCustomer(customerId);

// Disconnect from the DB, since we do not need DB action at this time
// anymore.
_unitOfWork.Disconnect();

}

public void OKButton_Click(object sender, EventArgs e )
{
// Reconnect to the DB
_unitOfWork.Reconnect();

ITransaction tx = _unitOfWork.BeginTransaction();
_custRep.Save (_customer);
tx.Commit();
}
}

I don't know if there's any better / cleaner way of doing this... If you know one, please let me know. :) It is offcourse cleaner if you could abstract the use of NHibernate's ISession by creating a class which encapsulates the ISession, but I wanted to keep things a bit sparse. :)

vrijdag 27 april 2007

Article: NHibernate best practices with ASP.NET

Billy McCafferty has written an excellent article on NHibernate and Domain Driven Design. It can be found here on the CodeProject.
Although it is focused on using NHibernate in ASP.NET, it is still very interesting even if you do not develop in ASP.NET. He talks about a few key concepts in DDD, and the example code is also very interesting.
There's one little drawback however in his example code: although he mentions that the way of working he demonstrates should work for Winforms development as well, I do not completely agree on that. However, I've to investigate it a bit more, which I'll do as soon as I find some time. Once done, I'll post my findings offcourse.

zondag 22 april 2007

Split

When I started this weblog in december 2005, I decided to blog about software development and about photography.

Now, 1 and a half year later, it seems to me that this was not such a good idea; I feel that software engineering and photography do not share the same audience.
Now, you probably think, did it really take you that long to acknowledge this fact ? Well, not really: during the first few months of blogging, the number of photography posts here was pretty low. At this time, I've noticed that 3 out of the 5 last posts were tagged with 'photography', so that's why I've finally decided to split things up.

This will remain my weblog that is focussed on programming (notice that I've changed the name from 'weblog' to 'devlog' as well :) ). Things that are focused on photography will appear on my photolog, so if you're interested, you can have a look there :).

I've choosen Wordpress to host my photo-blog, since Wordpress allows me to import posts from blogger, and that's what I've done: I've imported all the 'photography-tagged' posts from this weblog in my wordpress photo-blog, and translated them to dutch.

vrijdag 13 april 2007

.NET 1.1: Problems when selecting rows from a DataTable using an aggregate filter

I came accross a rather weird error today when I was working in C# 1.1. I was trying to select the records that exist in a DataTable that had more then one child in a related datatable.


To make things a little bit more clear, I've reproduced this by creating a Typed Dataset which contains 2 tables from the Northwind database:



What I want to do, is to select the Categories for which there are multiple products classified into.
So, this is what I've done; I created an instance of this dataset, and populated it with some data:

NorthwindDS ds = new NorthwindDS();
NorthwindDS.CategoriesRow c1 = ds.Categories.NewCategoriesRow();
c1.CategoryID = 1;
c1.CategoryName = "Category 1";
ds.Categories.AddCategoriesRow (c1);

NorthwindDS.CategoriesRow c2 = ds.Categories.NewCategoriesRow();
c2.CategoryID = 2;
c2.CategoryName = "Category 2";
ds.Categories.AddCategoriesRow (c2);

NorthwindDS.ProductsRow p1 = ds.Products.NewProductsRow();
p1.ProductID = 1;
p1.CategoryID = 1;
p1.ProductName = "Product 1";
ds.Products.AddProductsRow (p1);

NorthwindDS.ProductsRow p2 = ds.Products.NewProductsRow();
p2.ProductID = 2;
p2.CategoryID = 1;
p2.ProductName = "Product 2";
ds.Products.AddProductsRow (p2);

// The following line is important to illustrate the problem :)
ds.AcceptChanges();

This is pretty simple, I've just populated the Dataset with 2 categories and 2 products, and the 2 products are both linked to Category 1.
Now, the Query I've talked about earlier should thus return 1 Category, specifically, Category 1, since there's more then one product related to this category.
I do this using the following code:

string filterExpression = "COUNT (Child.CategoryID) > 1";
DataRow[] dr = ds.Categories.Select (filterExpression);

foreach( NorthwindDS.Category cat in dr )
{
Console.WriteLine (cat.CategoryName);
}

This gives me the expected result, it writes 'Category 1' to the output-window.
However, suppose that I've populated this Dataset with data coming from the Database, and that I add a product - record to this Dataset after the Dataset has been populated...
I can simulate this by adding a ProductRow to the DataSet after the 'AcceptChanges()' call:


// previous lines which create the dataset, and add the categories
// and the first 2 products are left out for brevity
ds.AcceptChanges();

NorthwindDS.ProductsRow p3 = ds.Products.NewProductsRow();
p2.ProductID = 3;
p2.CategoryID = 1;
p2.ProductName = "Product 3";
ds.Products.AddProductsRow (p3);

filterExpression = "COUNT (Child.CategoryID) > 1";
DataRow[] dr = ds.Categories.Select (filterExpression);

foreach( NorthwindDS.Category cat in dr )
{
Console.WriteLine (cat.CategoryName);
}

Now, I would expect that this gives me the exact same result as before, however, I get an exception:

An unhandled exception of type 'System.Data.VersionNotFoundException' occurred in system.data.dll

Addition information: There is no original data to access.

Probably, .NET wants to access the original contents of my new ProductRow, but since it is a new one, it has no Original DataViewRowState ...
I've tried to work around this by specifying that the CurrentRows should be used:

ds.Categories.Select (filterExpression, 
string.Empty,
DataViewRowState.CurrentRows);

But, to no avail. (Which didn't surprise me, because this line just says: return the Current DataViewRowState of the Categories and the problem seems to occur when the Product datarows are accessed).

So, this seems to be a bug in the .NET 1.1 (I've tried this in .NET 2.0 as well, and there, it works like a charm).

So, is there anybody who knows how to solve or work around this issue ?

zondag 1 april 2007

Tagliatelle - scampi

Tagliatelle - Scampi

vrijdag 9 maart 2007

Oudenaarde by Night

Yesterday evening, I've been walking around in Oudenaarde - the city were I'll be living in in the near future -, and I've taken these photographs.

oudenaarde stadhuis

oudenaarde walburga carillon

zondag 25 februari 2007

DDD: implementing persistence using NHibernate

Introduction

At last, I've found some time to sit down and begin writing what should be the last part of this 'Domain Driven Design Quickstart' series of articles. In this final article, I will implement the persistence of the domain model that I’ve created in the previous parts of this series. (part I, part II and part III).

To implement the persistence functionality of the domain model, I will use an O/R mapper. I’ve opted to use NHibernate as O/R mapper for this project.
I will not make an in-depth coverage of NHibernate in this article, since this is a bit beyond the scope of this article. Besides, there are various excellent resources on (N)Hibernate available. The book Hibernate in Action, for instance, is an excellent resource to learn about (N)Hibernate, and it offers also some more insights in the O/R principle.


The Database Schema

To get the information in a database, we need a database first (clever :) ). So, I’ve created this ERD:



I’m not going to elaborate on this database-schema since I presume that you have enough knowledge of databases / database-modelling, etc… So lets hop to the next phase.

NHibernate configuration

NHibernate is an O/R mapper which lets you persist your data to a number of supported databases. To be able to use it however, it needs to be setup properly; in .NET this can be easily done in the configuration file of your project.
For this project, I’ll create a WinForms application, and I’ll make some changes to the app.config file to configure NHibernate. This is done like this:


<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="nhibernate"
type="System.Configuration.NameValueSectionHandler,
System, Version=1.0.5000.0,Culture=neutral,
PublicKeyToken=b77a5c561934e089"/>
</configSections>
<nhibernate>
<add key="hibernate.connection.provider"
value="NHibernate.Connection.DriverConnectionProvider"/>
<add key="hibernate.dialect"
value="NHibernate.Dialect.MsSql2000Dialect"/>
<add key="hibernate.connection.connection_string"
value="Data Source=localhost;
Initial Catalog=SomeShop;
Integrated Security=SSPI"/>
</nhibernate>
</configuration>

As you can see, I need to define the nhibernate configuration section first. Once this is done, I specify to which type of database NHibernate will have to talk to (SQL Server 2000), and I also specify the connection string that must be used.

If you use Microsoft Visual Studio.NET 2005, you might come across some unwanted error/information messages concerning the nhibernate config section. I’ve written another post about this problem, and how to solve it a while ago. You can read it here.

Now we’ve configured our project to use NHibernate, but we also need to tell NHibernate how our classes should be mapped to our database-schema. This can be done by creating NHibernate mapping files which describe how a class should be represented in the database. Those mapping files are nothing more then XML files. As I’ve said earlier, this is not an NHibernate tutorial, but merely an article on how NHibernate can be incorporated in a Domain Driven Design project. Therefore, I will not post all the mapping files here or explain them in detail. I will post 2 mapping files here however, and explain them a bit.

NHibernate mapping files

For each class in my domain model, I create an NHibernate mapping file in my Visual Studio.NET project which contains my business classes.
In this specific case, I have a Class Library project which contains the ‘Customer’, ‘Order’, ‘OrderLine’, etc… business classes, so it is in this class library that I also create the NHibernate mapping files.

The mapping file for the Order class, for instance, looks like this:

<xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="SomeShopDomain.Order, SomeShopDomain"
table="[Order]" lazy="false">
<id name="Id" column="OrderId" type="Int32"
unsaved-value="-1"
access="field.camelcase-underscore">
<generator class="identity" />
</id>
<property name="OrderDate" column="OrderDate"
access="field.camelcase-underscore" />
<property name="Status" column="OrderStatus"
access="field.camelcase-underscore" />
<property name="Discount" column="Discount"
access="field.camelcase-underscore" />

<many-to-one name="OwningCustomer" column="CustomerId"
class="SomeShopDomain.Customer, SomeShopDomain"
not-null="true"
access="field.camelcase-underscore"
/>

<bag name="OrderLines" cascade="save-update"
inverse="true"
access="field.camelcase-underscore">
<key column="OrderId" />
<one-to-many class="SomeShopDomain.OrderLine, SomeShopDomain"/>
</bag>

</class>
</hibernate-mapping>

This is not the most simple mapping-file in the project, since the Order class contains a collection of OrderLines, so this relationship is reflected in the mapping file.

But, it is maybe better if I just explain the complete mapping file a bit .

As you can see at the beginning of the file, this file describes how the Order class should be mapped to the Order table in the database.
The 'id' element tells NHibernate that the Id property of the class should be used to identify each Order. This element also defines that the Id property of the class maps to the OrderId column in the Order table. The data-type is also defined in there, and it is stated that instances of the Order class that have a value of -1 for the Id property, are New/transcient (unsaved).
Now, NHibernate will use the Id property of the Order class to get or set the value of the Id.
This however, has some disadvantages in my opinion: what if you have some specific logic in the setter-part of the property, some validation-logic for instance ? When NHibernate loads an object out of the database, should this logic be executed ? In my humble opinion not. When an object is loaded from a persistent state, the values of the object must be set, without performing any extra logic.
Another problem pops up when the property is read-only. In this case, Id is an 'identification', and the programmer that uses the Order class, shouldn't be able to change this property. Therefore, this property has only a getter in the Order class, and no setter. NHibernate will have a problem with that: it will throw an exception saying that it cannot set the value of the Id property since it has no setter.
That's why I use the access attribute. With this attribute, I tell NHibernate that it should use the field instead of the property, and that it can find this field by taking the property-name that I've defined in the mapping file, prefix it with an underscore, and make the first character lowercase.
So, in this case, instead of setting the Id property, NHibernate will look for a field in the Order class which is called _id and give this field the value of the OrderId column. By using the field instead of the property, I'm always sure that no extra logic will be executed, and I do not have to bother with getter-only properties.
You can read more about this here and here Particulary in the comments of these articles.
The following three properties are quite straightforward. These elements just say to which column each property maps, and I've also defined that NHibernate should use the field instead of the property to get / set these properties.

The next two elements are bit more interesting though.
The many-to-one element defines how the relationship between Order and Customer must be saved. As you might remember, the Order class holds a reference to the Customer to which the order belongs. To be able to populate the OwningCustomer property which contains this reference, and to be able to save the link with the Customer when the Order is saved, the many-to-one element is used. A Customer can have many Orders, and an Order always belongs to one Customer. The many-to-one element just says that the OwningCustomer property maps to the CustomerId column in the Order table, and that the OwningCustomer is of the type SomeShopDomain.Customer. By defining this type, NHibernate knows that it should look for a mapping file which should be called SomeShopDomain.Customer.hbm.xml in where the mapping of the Customer type is defined.
Mapping files should be named after the class for which they contain the mapping, and should have the extension hbm.xml. Next to that, you also have to specify 'embedded resource' as build action for the mapping files.
The <bag> element defines that the Order contains a collection of OrderLines, and that these objects must be of type SomeShopDomain.OrderLine. NHibernate will use the mapping-file of the OrderLine class to determine in which table those OrderLines must be saved.
The <key> element states that the Id of the current Order must be saved in the OrderId column of the table where the OrderLines will be saved.


This concludes the quick tour of the NHibernate mapping file. For more information about the possible elements, I'll refer to the Hibernate in Action book, or to the Hibernate documentation.

The mapping file of the OrderLine class, looks like this:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="BlogShopDomain.OrderLine, BlogShopDomain"
table="OrderLine" lazy="false">
<id name="Id" type="Int32"
column="OrderLineId"
unsaved-value="-1"
access="field.camelcase-underscore">
<generator class="identity" />
</id>
<property name="ArticleName" column="ArticleName"
access="field.camelcase-underscore" />
<property name="ArticlePrice" column="ArticlePrice"
access="field.camelcase-underscore" />
<property name="ArticleId" column="ArticleId"
access="field.camelcase-underscore" />
<property name="NumberOfItems" column="NumberOfItems"
access="field.camelcase-underscore" />

<many-to-one name="OwningOrder" column="OrderId"
class="BlogShopDomain.Order, BlogShopDomain"
access="field.camelcase-underscore"
not-null="true" />

</class>
</hibernate-mapping>
I'm not going to elaborate on this file, so lets get to the next part. :)

Integrating NHibernate in the project

At this point, I've done some necessary configurations, but some coding needs to be done as well.
NHibernate uses the concept of Sessions as an 'interface' between your objects and the database. A session can be considered as a unit of work. This is a bit a simplistic definition, but you can find a better one in the Hibernate documentation or in Hibernate in Action.
To be able to create Sessions, you'll need a SessionFactory. Unlike Hibernate Sessions, a SessionFactory is an expensive object to instantiate, so it's best practice to create this object only once.
Therefore, I like to create a Singleton class which holds amongst some other stuff, the NHibernate ISessionFactory:

public class ApplicationSettings
{
private static ApplicationSettings _instance;

private ApplicationSettings() {}

// The only access point to the ApplicationSettings instance.
public static ApplicationSettings Instance
{
get
{
if( _instance == null )
{
_instance = new ApplicationSettings();
}
return _instance;
}
}

private ISessionFactory _sessionFactory = null;

public ISessionFactory SessionFactoryObj
{
if( _sessionFactory == null )
{
Configuration cfg = new Configuration();
cfg.AddAssembly (typeof(SomeShopDomain.Customer).Assembly);
_sessionFactory = cfg.BuildSessionFactory();
}
return _sessionFactory;
}

}

This structure guarantees that I'll have only one ISessionFactory in my project, and that this SessionFactory is created only once.
The code to create the ISessionFactory is quite simple; first of all a Configuration object is instantiated, and the assembly which contains the business classes is added to the Configuration. As you can see, I use reflection to find that assembly, since I don't want to be bothered with assembly-names and locations. After that, the BuildSessionFactory method is called which creates the ISessionFactory.
This ApplicationSettings class is not part of my class library which contains the domain, but belongs to the project that contains my client application (in this case, a WinForms application). More on that later.
At this time, we can create ISessions.

ISession s = ApplicationSettings.Instance.
SessionFactoryObj.OpenSession();

Creating Repositories for our Domain classes

In Domain Driven Design, getting objects from a persistence store, and getting objects into a persistence store, is being abstracted by the use of repositories.
As you might have seen in the previous articles of this serie, I've already created 'dummy' repositories for the unit-tests.
Now, it is time to implement the 'real' repositories, which will actually do the work of loading / storing objects to our database.
In the 2nd part of this serie, I've already mentionned the existence of the DomainSettings class and the RepositoryFactory interface.
At that point, I've only implemented the 'mock-repositories', but now, I want to implement repositories which use NHibernate to do some real work. This means that I'll have to create an NHibernateRepositoryFactory class. I choose to put this class, along with the NHibernate-repositories in the same project / assembly where my business classes reside.
The NHibernateRepositoryFactory class must implement the IRepositoryFactory interface, which looks like this:

public interface IRepositoryFactory
{
ICustomerRepository CreateCustomerRepository();
IOrderRespository CreateOrderRepository();
...
}

There's one caveat here however... When using databases you'll be faced with 'Transactions'. A repository should not be the initiator nor the 'committer' of a transaction.
Why? The repository has no knowledge of the 'context' of the situation. The repository does not know when it should initiate and commit or rollback a unit-of-work.
As I've told earlier in this article, the NHibernate Session object is the NHibernate object which 'controls' a unit-of-work. Therefore, I'd like to extent the IRepositoryFactory interface with methods which allow me to create a specific repository with an object which is responsible for transaction-handling injected into it:

public interface IRepositoryFactory
{
ICustomerRepository CreateCustomerRepository();
IOrderRespository CreateOrderRepository();
...

ICustomerRepository CreateCustomerRepository( object transHandler );
IOrderRepository CreateOrderRepository( object transHandler );
}
This allows me to create repositories which can take part in a specific transaction/unit-of-work, and it also allows me to create repositories without having to take care about transactions. (This is also necessary; as you can see in the code in the Customer class in part 2 of this serie. There I need to retrieve a value, which is given to me by a repository. In this case, I do not really need a transaction context).

I've chosen to define the transHandler in my CreateXXX methods in the IRepositoryFactory as an object, since I do not want to couple the IRepositoryFactory interface with NHibernate.

At this time, I can already start writing an implementation of a NHibernateRepositoryFactory:

public class NHibernateRepositoryFactory :
IRepositoryFactory
{
public IOrderRepository CreateOrderRepository()
{
ISession s = DomainSettings.Instance.SessionFactoryObj.OpenSession();
return new NHibernateOrderRepository(s);
}

public IOrderRepository CreateOrderRepository( object transHandler )
{
// convert the transHandler to an NHibernat ISession object.
ISession s = transHandler as ISession;

if( s == null )
{
throw new ArgumentException ("object of type NHibernate.ISession expected.",
"transHandler");
}

return new NHibernateOrderRepository (s);
}
}
The NHibernateOrderRepository can look like this:
public class NHibernateOrderRepository :
IOrderRepository
{
private ISession _context;

public NHibernateOrderRepository( ISession s )
{
_context = s;
}

public Order GetOrder( int id )
{
return _context.Get (typeof(Order), id) as Order;
}

public decimal GetOrderTotalForCustomerSinceDate( Customer c, DateTime date )
{
string hql = "select sum (ol.NumberOfItems * ol.ArticlePrice) " +
"from Order o, " +
"OrderLine ol, Customer c " +
"where ol.OwningOrder = o and o.OwningCustomer = c " +
" and c.Id = :custId and o.OrderDate >= :orderDate";

IQuery q = _context.CreateQuery (hql);
q.SetInt32 ("custId", c.Id);
q.SetDateTime ("orderDate", date);

object o = q.UniqueResult ();

if( o == null || o == DBNull.Value )
{
return 0;
}
else
{
return Convert.ToDecimal (o);
}
}
}
I will not elaborate here on the HQL and the specific ISession methods which I've used in the code above, since this would be truly outside the scope of this article. For more information, I'd refer -again- to the Hibernate documentation or the Hibernate in Action book.
I do like to mention though that the bug which I've mentionned here is fixed in NHibernate 1.2.0 CR1. :)


As I'm typing this, I now also see that it would be better to let the repositories implement the IDisposable interface. In the Dispose method. In the Dispose method of the NHibernateRepositories, I can then check if my _context is still open, and close it if it is.
Then, I should also change the code in the Status property of the Customer class, so that it looks like this:

public CustomerStatus Status
{
get
{
CustomerStatus result = CustomerStatus.Normal;

using( IOrderRepository or =
DomainSettings.Instance.
RepositoryFactoryObj.
CreateOrderRepository () )
{
decimal orderTotal = or.GetOrderTotalForCustomerSinceDate(this,
DateTime.Now.AddMonths (-3));

if( orderTotal > DomainSettings.GoldAmountTreshold )
{
result = CustomerStatus.Gold;
}

}
...
return result;
}
If I don't do this, the ISession which is used by the OrderRepository would be kept open.


Using NHibernate in the client application

Now that we've seen (albeit rather quickly) how we can use NHibernate, it is time to integrate it in the client application.
Because of the way NHibernate works when it has to save changed objects back to the DB, I'd like to use long living sessions.
When you retrieve an object from the database, NHibernate will keep this object in the Session. When you save the object back to the database, NHibernate will try to find the object in the ISession instance which is used to perform the save. If the instance is found, NHibernate will update the corresponding record. If the instance is not found, NHibernate will create a new record.
If you use a separate ISession to retrieve an object from the DB, and use another ISession to persist this object back to the DB, NHibernate will asume that it has to insert a new record.
Therefore, it is -imho- best to use the same ISession instance for retrieving and saving the same business object instance.
When you're using NHibernate in Windows applications, you can do this by using the 'long conversation' model.

In short, this means that you can keep your session open as long as the user is busy with a 'unit-of-work', but you can disconnect your session from the database when no database-access is needed for a while.

Although this article doesn't provide really in-depth information, I'd like to finish it here. This is yet another article which is way to long (maybe I should stop writing such long posts), but if you've gotten to here, please feel free to post any comments, critics, remarks, ...

woensdag 31 januari 2007

Meet My Mom

In the past few weeks, I've been making some portraits. Some of them in a studio, others 'on location'.
I will post some of the results here and I'll start with a portrait of my mother.

These photographs are shot in her 'study room'; my mom loves painting and calligraphy (she's pretty good at it) and I wanted to express this in my photographs.


high iso portrait creative mother
Just a pity that she's holding the pen a little bit to high


high iso portrait creative mother2

The photos have been taken with ambient light (I don't like to use flash for location-portraits). I've used a Nikon D200 with a 50mm f/1.8 lens mounted on it. Since there was not too much light available, I've choosen a small aparture number and a high ISO setting. (The EXIF information is available in the picture; you can easily view it using Opanda IEXIF Viewer"). Despite the high ISO setting, I've to admit that I'm pleasantly surprised with the noise levels in these photo's.

zaterdag 20 januari 2007

Lambda expressions in .NET

In C# 3.0, there will be a new feature available: lambda expressions. This new feature was necessary to create the LINQ feature, which will also be introduced in C# 3.0

Today, I came across an interesting article written by Howard Dierking in where he explains what lambda expressions are, and how you can use them.
Very nice and clear article.

Tagged

Seems that I've been tagged by Mike Nichols, so I'm supposed to come up with 5 things you don't know about me; here goes:


  • I've started playing music when I was about 8 or 9 years old. I've played guitar until I was about 16 years old. At that age, I stopped playing music. I didn't wan't to do it anymore. I was supposed to go to music classes each wednesday afternoon, and each saterday morning and I wanted to do other things during that time. :) Sometimes, I regret it though that I didn't continue with that guitar-thing. (I still have my guitar though, and maybe I'll pick it up again in the future)

  • I don't like cheese.
    Well, that's not completely true; I don't eat cheese 'as is', but I do like food that has cheese as an ingredient (pizza, croque monsieur, tiramissu, heck I even like cheese-burgers). I also like Cheetos. Weird huh?

  • I started programming relatively late. I was 17 years old when I wrote my first computer program.

  • I always wanted to become a pilot. Not on airliners, but a jet pilot. :) At age 16, I've sent a letter to the Belgian Air Force to enquire for more information about this. A few days later, I've received an information bundle about it. Unfortunately, I never took part in any of the 'promotions' of the Belgian Air Force. Maybe I was already realistic about my chances: there are only very few positions (about 4 each year) and numerous candidates.
    I haven't lost my interest in jets though; I still like to visit air-shows (although since a plane crashed at the Ostend Airshow in 1997, air-shows in Belgium aren't what they used to be...).
    If I would ever have the chance to be a passenger in a two-seater, I'd certainly do it!

  • I do like karting. Until a few years ago, I used to do it at least once a week. Unfortunately, I'm not able to keep up that frequency right now. I'm already happy if I can go karting once a month.
    I also dream of driving an open-wheel formula race car once (Formula One, Formula Ford, F3000, ... whatever

The 5 persons I'm tagging are: PJ van de Sande, Peter Veentjer, Jelle-Jan Van Veelen, Valentijn and Evan Hoff

woensdag 10 januari 2007

Left- and RightPadding in SQL Server

Although SQL Server contains a few string manipulation functions, there exists no function that allows you to left- or rightpad a string expression.
This is a bit of a pity, since left- and rightpadding is sometimes necessary.

But, no one stops you from creating your own LPAD and RPAD function offcourse; in fact, it is rather very simple. :)
Although SQL Server doesn't provide padding methods out of the box, it doesn't require a lot of work to pad a string.


For instance: suppose you have a variable @number, which contains a number. If you need to leftpad this string with zeroes so that it always contains 8 characters, you simply have to do this:

SELECT RIGHT ('00000000' + @number, 8)

If @number contains '81337', this statement will return '00081337'.

With this knowledge, it is pretty simple to create your own LPAD method. This is the code:

CREATE FUNCTION [dbo].[LPAD] (@string VARCHAR(8000), 
@length INT,
@paddingChar CHAR(1))
AS
BEGIN
RETURN RIGHT (REPLICATE (@paddingChar, @length) + @string, @length)
END

Creating an RPAD function is very similar:

CREATE FUNCTION [dbo].[RPAD] (@string VARCHAR(8000),
@length INT,
@paddingChar CHAR(1))
AS
BEGIN
RETURN LEFT (@string + REPLICATE (@paddingChar, @length), @length)
END

As you might have noticed, REPLICATE is a SQL Server function which repeats a specified characters a number of times. :)