Archive for March, 2009

Implementing A Value Object With NHibernate

12 commentsWritten on March 25th, 2009 by
Categories: NHibernate

I've covered implementing a Value Object before, but this post is about using Value Objects with NHibernate. First, a little recap of what a Value Object is for those who don't know yet.

A Value Object (also known as Immutable Object) is basically an object without a conceptual identity. A Value Object is defined through its inner values, and not an identity like Entities. This means that a Value Object’s inner values can not be changed after object creation, hence the term Immutable Object. Should you need to change the inner values of the Value Object, you should actually create a new Value Object.

For some of you, this might seem odd. But you’ve actually used Value Objects on many occasions already. In .NET, strings are Value Objects. So are DateTime instances. If you create a string, you can’t modify its inner value. If you do, a new string is actually created. Same thing with a DateTime. The DateTime class provides methods to add days, hours, seconds, whatever… but those methods never modify the instance’s inner value. Instead, they return a new DateTime object because each DateTime instance is immutable.

This has interesting consequences on object equality. Two Value Objects holding the same data should be considered identical objects, even though they are 2 different instances. A Value Object should therefore properly implement the Equals and GetHashCode methods.

For this example, we'll define a Name class, which is a Value Object consisting of 2 values: FirstName and LastName. If 2 people have the same first and last name, you could say that they have the same 'name', right? We'll just ignore middle names here... The combination of a FirstName and LastName would make for a good Value Object. We need to make sure that once an instance of the Name class has been created, none of its values can be modified. We also need to make sure that multiple instances of the Name class that have the same values can be safely considered equal to each other. The code of the Name class looks like this:

    public class Name : IEquatable<Name>
    {
        private readonly string firstName;
        private readonly string lastName;
 
        public Name(string firstName, string lastName)
        {
            this.firstName = firstName;
            this.lastName = lastName;
        }
 
        // the default constructor is only here for NH (private is sufficient, it doesn't need to be public)
        private Name() : this(string.Empty, string.Empty) {}
 
        public string LastName
        {
            get { return lastName; }
        }
 
        public string FirstName
        {
            get { return firstName; }
        }
 
        public bool Equals(Name other)
        {
            if (ReferenceEquals(null, other)) return false;
            if (ReferenceEquals(this, other)) return true;
            return Equals(other.firstName, firstName) && Equals(other.lastName, lastName);
        }
 
        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            if (ReferenceEquals(this, obj)) return true;
            if (obj.GetType() != typeof(Name)) return false;
            return Equals((Name)obj);
        }
 
        public override int GetHashCode()
        {
            unchecked
            {
                return (firstName.GetHashCode() * 397) ^ lastName.GetHashCode();
            }
        }
 
        public static bool operator ==(Name left, Name right)
        {
            return Equals(left, right);
        }
 
        public static bool operator !=(Name left, Name right)
        {
            return !Equals(left, right);
        }
    }

Take a close look at the constructors. The public constructor takes both required values (firstName and lastName), and assigns them to the private fields. The default constructor (which we've made private) merely calls the public constructor and passes String.Empty to the public constructor's parameters. As you can gather from the comments on the private constructor, it's only reason for existence is because NHibernate requires classes to have a default constructor. Well actually, that's not entirely accurate since it is possible to use classes without a default constructor but it's not trivial do so.

Creating a private default constructor seems to be a reasonable alternative. Developers can't create invalid Name instances (unless they cheat with reflection), and NHibernate can use the private constructor so it can create the instances before it fills the fields with the values from the database.

Note: NHibernate allows a private default constructor for Value Objects, but for Entities you will need a default public or protected constructor as private is not sufficient.

We can now use this Value Object in every entity we want by simply adding a property to the entity like this:

        public virtual Name Name { get; set; }

The mapping of the Value Object must be added to the mapping of the entity like this:

    <component name="Name" class="NHibernateExamples.Values.Name" insert="true" update="true">
      <property name="FirstName" column="FirstName" type="string" length="50" not-null="true" access="nosetter.camelcase" />
      <property name="LastName" column="LastName" type="string" length="50" not-null="true" access="nosetter.camelcase" />
    </component>

Notice the value of the access attribute. It's set to nosetter.camelcase. That means that NHibernate will use the get property when reading the values, but it will use a camelcase private field to set the values when it's creating the object with values from the database.

Entities: Required Properties And Properties That Shouldn’t Be Modified

19 commentsWritten on March 24th, 2009 by
Categories: NHibernate

How often do you see entities mapped with getters and setters for every property, and only a default constructor (either added implicitly by the compiler or explicitly by a developer)? It's not really the best way to map entities, so i just wanted to show a better way of doing this.

Consider the OrderLine entity. It has 4 required properties: Order, Product, UnitPrice and Quantity. It also has one optional property called DiscountPercentage. The Order and Product properties should never be changed after the OrderLine was created. It also has a database Id property which should never be changed either.

This is how the code of the OrderLine class would look like:

    public class OrderLine : IIdentifiable<int>
    {
        public OrderLine(Order order, Product product, decimal unitPrice, int quantity)
        {
            if (order == null) throw new ArgumentNullException("order");
            if (product == null) throw new ArgumentNullException("product");
 
            this.order = order;
            this.product = product;
            UnitPrice = unitPrice;
            Quantity = quantity;
        }
 
        // required for NH
        protected OrderLine() {}
 
        private int id;
 
        public virtual int Id
        {
            get { return id; }
        }
 
        private Order order;
 
        public virtual Order Order
        {
            get { return order; }
        }
 
        private Product product;
 
        public virtual Product Product
        {
            get { return product; }
        }
 
        public virtual decimal UnitPrice { get; set; }
        public virtual int Quantity { get; set; }
        public virtual double? DiscountPercentage { get; set; }
    }

There is only one public constructor, which takes all of the required properties as parameters. The protected constructor is only there because NHibernate needs it to create run-time proxies (which enable all of the lazy-loading magic). In theory, you can't create instances of the OrderLine entity without its required data.

Also, notice how the Id, Order and Product properties only have a getter, and no setter. These values can no longer be changed by developers once the object is constructed. The UnitPrice and Quantity properties do have setters, because these values can be modified after the entity is created.

The mapping for this class looks like this:

  <class name="OrderLine" table="OrderLine" >
    <id name="Id" column="Id" type="int" access="nosetter.camelcase" >
      <generator class="identity" />
    </id>
 
    <many-to-one name="Order" column="OrderId" class="Order" not-null="true" access="nosetter.camelcase" />
    <many-to-one name="Product" column="ProductId" class="Product" not-null="true" access="nosetter.camelcase" />
    <property name="UnitPrice" column="UnitPrice" type="Decimal" not-null="true" />
    <property name="Quantity" column="Quantity" type="int" not-null="true" />
    <property name="DiscountPercentage" column="DiscountPercentage" type="double" />
  </class>

It's pretty easy... each property that shouldn't be changed after creation is mapped with the nosetter.camelcase access strategy. That means NHibernate uses the private field to set the value directly after creation, but will use the getters whenever it needs to read the data from the entity.

As you can see, without too much trouble you can make sure that your entities always have their required data, and that properties that shouldn't change after creation can't be modified either.

Registration For My NHibernate Talk Is Open

7 commentsWritten on March 23rd, 2009 by
Categories: Off Topic

Ok, apparently you can now register for the Visug session where i will be talking about NHibernate.

The session is called ORMs: Entity Framework vs NHibernate, and the Entity Framework part will be covered by Kurt Claes. The location is yet to be announced but the date is September 10, 2009.

There is a maximum of 60 attendees and 20 spots are already taken so hurry up and register ;)

What Would You Like To See In My Upcoming NHibernate Examples?

9 commentsWritten on March 22nd, 2009 by
Categories: NHibernate

The original version of my NHibernate Mapping Examples was pretty popular, but they were based on NHibernate 1.2 and only showed some of the basics. I have plans to create a completely new version of these examples based on NHibernate 2.1. I want the examples to be suitable for people who are entirely new to NHibernate as an easy way to learn, as well as offering value to experienced NHibernate users by showing off some more advanced features.

It would be a downloadable Visual Studio solution, consisting of 2 projects. One being the mapping files and the POCO's, the other being a test (as in: consisting of automated tests) project which would contain the code of various usage scenarios to demonstrate various features of NHibernate.

I already have some ideas of stuff i definitely want in these examples, but i'd also like to hear from you what you would like to see in these examples. So, if there is anything you'd like to see in there, let me know :)

Obviously, i can't promise that everything you ask for will be included but i'll try anyway ;)

What I’d Like To See At Microsoft’s Technical Events

20 commentsWritten on March 19th, 2009 by
Categories: Opinions

As some of you may have read, i commented recently on why i wasn't interested in going to the TechDays event. Tom Mertens, the organizer of the event, disagreed with my "questionable content, bad marketing"-statement and wanted to know what kind of content would make me want to attend these events.

First of all, i want to see more love for the Open Source Software (OSS) world within the .NET community. Like it or not, deny it if you want, but an ever increasing number of .NET developers are making use of OSS libraries/frameworks. No matter what Microsoft's official stance on this matter is, they can't reasonably deny that this has a positive effect on the entire .NET platform. So why is there so little attention to this portion of the .NET community? I want sessions on NServiceBus, NHibernate, Castle Windsor, StructureMap, NInject, PostSharp, Castle Monorail, etc... There's no reason why competing Microsoft products (Entity Framework, Unity, ASP.NET MVC, Enterprise Library, ...) should get a lot of attention while other (and in some cases, more mature and powerful) alternative solutions to the same problem are largely ignored.

Next up, the obsession with Drag-n-Drop Development (the other kind of DDD). I don't care how easy some of these things can be... i care about how well these things scale. To be more specific, i want to know how well these things scale in terms of performance, code complexity, and the number of developers in a team that perform similar tasks. The typically glorified "Hello World" examples really don't cut it. I want real world code. I want real world complexity and problems. I want solutions that are viable in the real world, i don't care how well you can sell your Hello World solution.

I also want more focus on proper software development practices. I want more focus on readable code, testable code, reducing complexity (in real world situations), improving maintainability, enabling scalability, basically anything that enables us to produce higher quality code. When i ask people what their favorite sessions were, i almost always hear them mention sessions that deal with solving problems... either performance issues, or weird, hard to debug bugs. Pinpointing problems and fixing them are extremely important skills, but shouldn't we all focus just a little bit more on avoiding problems in the first place?

That brings me to the speakers. I don't want to offend anyone specifically, but i know for a fact that i wouldn't want some of those MVP's doing presentations to go anywhere near my code. And that statement is not based on the work they've put out on their blogs or in presentations or anything in public. It's based on what they did while they were doing their job at clients. You know, real world stuff. Give me sessions by Ayende, Greg Young, Phil Haack, Scott Hanselman and others like them. And yes, i know the people i listed are either MVP's or even Microsoft employees. I don't care. These people genuinely care about quality instead of just their own career. That is what i want from speakers. From every single one of them.

Basically, give me an ALT.NET track. You don't even need to call it ALT.NET... that name is a double-edged sword so i wouldn't blame anyone for avoiding associations to it. But give me that type of content, those type of speakers. Even better, put all of that stuff in one day of the conference/event. I'd be hesitant to go for 3 days to get a good session here or there, but if there's one day where i can spend the entire day going to the type of sessions and speakers i mentioned above, i'd be more than willing to pay out of my own pocket to go. And of all of those 1650 attendees, and despite the 95% approval rating of those who bothered to submit evaluations, how many of them could honestly say that they'd be willing to pay for the event out of their own pocket?