.net and other musings

Ben Lovell, an agile developer living in the UK.

Category: NHibernate

MonoRail & ActiveRecord tips

Adam Esterline has posted a bunch of MonoRail & ActiveRecord tips over on his blog. Some of the detail is fairly standard stuff but I learned a few things: MARS on SQL Server 2005 being one of them.

One thing I would add to the ActiveRecord tips is be mindful of lazy-loading on collection mappings. Especially now we have DetachedCriteria and the ability to be explicit about fetching strategies. Lazy-loading big lists can be pretty disastrous to application performance when used in the wrong place. For example: when traversing every node of a persistent object graph and touching unloaded collections.

Take a look at the NHibernate performance docs for more information.

NHibernate Query Generator

We should all be more than familiar with useful tools and commits coming from Ayende by now 🙂 However, the one I really dig is his NHibernate Query Generator.

NHQG is a console application which when pointed at your NHibernate mapping files, produces a bunch of partial classes for the types in your domain model which ultimately generate NHibernate DetachedCriteria. The real goodness is in the expressiveness of the querying API which they create.

Consider the following traditional NHibernate code:

IQuery query = session.CreateQuery("from Publisher as pub where pub.Name = :Name and pub.City = :City");
query.SetParameter("Name", "Test");
query.SetParameter("City", "London");
return query.List<Publisher>();

Using the NHQG generated helpers we can express this as:

return Repository.FindAll(
    (Where.Publisher.Name == name) && 
    (Where.Publisher.City == city));

Via nifty operator overloading and generics magic we end up with the Where syntax. Obviously this example just touches the surface of what we can do but don’t you agree how nice the 2nd approach is. The generated code supports navigating the relationships, ordering etc as you would expect.

Ayende prefers the no-strings approach. I tend to agree!

Infrastructure Ignorant/Anemic domain model?

An example project I put together recently highlighting recommended baseline architecture has got me thinking about the best approach to domain driven design and incorporating the Domain Model.

The domain model dictates that your entities encapsulate business logic. In facilitating such a requirement your model classes stray from the traditional POCO principles and can end up incorporating infrastructure artifacts such as persistence code and the like. The extreme end of this is being something like an ActiveRecord enabled model – whereby your ORM mappings are essentially C# properties adorned with attributes. This approach has a nasty whiff of Code Smell to me. Other evidence of this can include:

  • Having to derive from special classes defined in your ORM framework
  • Implementing special logic or types defined by your ORM framework
  • Redefining object identity for ORM purposes
  • Adding references to libraries required by your ORM framework

A concrete example of this is when trying to serialize entities from an NHibernate and lazy-loading enabled domain model. Due to the cruft required by NHibernate when proxying lazy-loaded collections, certain un-serializable types are introduced. Of course, the way around this side effect is to create Data Transfer Objects and move your data across the wire in this manner.

When layering in application design, the domain model naturally falls into the vertical. When enforcing strict layering the Anemic Domain Model is the only (simple) approach worth considering. The anemic domain model describes a collection of entities exhibiting only data. They can exist outside of an ORM context and depend on fewer packages. Rather than perhaps exposing static methods on your model classes i.e:

Publisher publisher = Publisher.GetById(id);

The danger of this approach is that data access occurs wherever methods on the domain model are invoked. Also, does the domain model have much use if not enforcing the business rules in the domain? After all, the domain model is rarely, if ever a candidate for reuse. I certainly can’t think of any case where it would be.

The alternative is to move those responsibilities out into some form of repository, for example:

Publisher publisher = DefaultRepository<Publisher>.FindById(id);

And in doing so you remove all your persistence concerns from the model. The entities then simply become dumb data holders and any persistence occurs only in the layers you allow it to.

I’m still not sure whether I prefer the former or the latter. DD purists will of course advocate the former, however my experience has been firmly around the latter approach. Can anyone help me decide?

Excellent NHibernate domain driven design articles…

I stumbled across a 9 part article series (starting here) which would be a great read for someone starting out with NHibernate over on the b# blog. The articles covers the ins-and-outs of creating an NHibernate enabled domain model right down to the project structure and unit testing strategies. Worth a read!

RoR vs. Web Forms vs. MonoRail Pt2

Ok so in the last post I talked about some of the more obvious issues I have with ASP.NET and web forms development. Thankfully, the Castle Project’s MonoRail framework goes some way to alleviating that pain.

The Positives

MVC, MVP, ABC easy as 123…

Under the covers, MonoRail is a full MVC compliant framework essentially comprising a front controller sitting over the ASP.NET infrastructure intercepting specially formed URI’s. The HTML ends up in the browser via your choice of view engine, with NVelocity (a fork of the Jakarta Velocity port) the default and most accessible, Brail being the Boo dynamic language and most performant option and of course a cruddy web forms engine too which nobody should use. 🙂 I’ve been comfortably using NVelocity for a while now, and provide testament that its not difficult to pick up.

The controller code orchestrates the flow of logic through the application and rails URI’s map nicely to actions on the controller which are ultimately public methods on the controller class itself. All nice and easy. Actions exposed on controllers derived from the magical SmartDispatcherController can translate posted form values into domain model objects for you by simply adding the DataBind attribute to your action’s argument list:

public void Save([DataBind("publisher")] Publisher publisher)

In the above example the publisher argument is passed into the Save action fully constructed via the form or query string values posted! This saves on the usual binding and scraping stuff you normally do in web forms and which almost always ends up sitting in the code behind untested. Note: the databinding stuff is of course very flexible and my example above just touches on the possibilities.

ActiveRecord

The model can be supplied with an ActiveRecord enabled domain model. This of course abstracts away NHibernate behind the scenes. Unfortunately generic collections support doesn’t work right now but I believe that work is firmly underway.

Edit: Generic collections are supported, as long as you’re running from the trunk.

Domain entities are adorned with the necessary attributes defining how their properties are mapped to your data source. This is a departure from the usual hbm XML mapping files but just as expressive.

ActiveRecord also supplies simple validation in the form of special attributes including email validation, regular expression validation and the like.

UI Components

Reusability of UI components is achieved via ViewComponent. These can support nested sections, parameters etc.

AJAX and client scripting support

Built into MonoRail are a number of helpers which allow you to perform the usual AJAX stuff such as calling remote server side methods and callback support, Scriptaculous and Effects2 client side goodness. In fact the helper extensibility is a nice way of adding extensions and wrapping commonly performed functionality in the view.

Convention over configuration

Like RoR, MonoRail prefers convention over configuration. The project structure skeleton is the same throughout all MonoRail enabled solutions. The MonoRail installer also includes a handy templated solution provider for both VS.NET 2003 and 2005 to create the project skeleton and testing is included. Accustomed MonoRail developers can open any solution and just know where things are going to be.

Testability

One of the sore points of ASP.NET development was the unit testing difficulty. MonoRail overcomes this by enforcing the MVC pattern. Controllers are testable classes sitting outside of the usual ASP.NET cruft. There are a number of framework features within MonoRail which specifically aid testing.

Scaffolding

Like RoR, controllers adorned with the necessary scaffolding attributes can automatically produce the basic markup and logic for CRUD operations on your domain model. Handy for prototyping or creating rough-and-ready data entry capabilities in your applications.

Container support

MonoRail supports IoC via the Windsor container. Controllers and their dependencies/parameters can be injected by the container if necessary.

The negatives

MonoRail does have some negatives, which I will mull over:

No 3rd party or ASP.NET web forms controls support

I don’t really see this as an issue but can see that some ASP.NET developers will. Fans of the big UI library packages will complain, but there is this old concept of HTML and it is surprising how flexible it can be 😉 Most use of control libraries I have seen has been misguided, by this I mean they’re usually added to a screen just because they can.

The web forms control library isn’t such an issue as things like calendars, grids and the like are not to difficult to duplicate the MonoRail way.

Learning a whole bunch of new concepts/patterns/practices

Most ASP.NET developers are what can only be described as morts. They’re not familiar with design patterns and good practices such as clean separation since they came from either ASP or VB (procedural backgrounds) so this stuff doesn’t come naturally. If you’ve used NHibernate you’ll pick up the ActiveRecord stuff in no time. Learning the template syntax for your chosen view engine is of course another consideration.

Summary

In summary, the benefits of using MonoRail over web forms are clear. Clean separation of concerns, testability, reduced complexity and none of the web form cruft and artifacts. MonoRail won’t suit everybody, but even if you’re happy with web forms it’s definitely worth a look. Personally I think its the only way worth programming in the enterprise with ASP.NET today.

NHibernate: Using guid.comb for Identifiers

Jeffrey Palermo posts a nice article describing (and pointing to descriptions) why using the guid.comb identifier generator with NHibernate is a Good Thing.

Read On

NHibernate Tip: Escaping column names

Another quick NH tip. When escaping column names in mapping files, remember to use backticks i.e. `ColumnName` and not square brackets a la SQL Server i.e. [ColumnName]. NHibernate replaces backticks at runtime with the correct escaping sequence for your chosen database dialect thus aiding portability to other RDBMs.

While we're on the subject of databases and NHibernate, another little-known tip (for SQL Server) which a colleague mentioned to me: When specifying tables in your mapping files, prefix them with the database name and owner i.e. "Pubs.dbo.Authors". For a potentially significant performance increase when issuing complex queries via NHibernate. Although this does affect database portability slightly 🙂

NHibernate Tip: Controlling access to persistent collections

When exposing collections in your NHibernate mapped domain model one thing you should consider doing is restricting access to the collections. NHibernate allows you to specify an access strategy (and a complimentary naming strategy) – this essentially being a policy used by the NH internals to control how a type's members are accessed when it is hydrated/dehydrated by the NH framework.

By specifying an access strategy of nosetter and removing the setter from the property of the mapped collection you can control a client's ability to overwrite the actual collection reference. If you expose your collections (when mapping sets, lists or bags) typed to ICollection you can further enhance the usability of your persistent types. As the ICollection interface doesn't expose the Add, Remove and Clear methods on your collection you must provide your own implementation. This is convenient as it allows you to check for runtime type safety, nullability and any other logic you need to enforce. For example:

public class User
{
	...

public ICollection Roles
	{
		get
		{
			if(this.roles == null)
				this.roles = new ArrayList();

return this.roles;
		}
	}

public int AddRole(Role role)
	{
		if(role == null)
			throw new ArgumentNullException("role");

return ((IList)Roles).Add(role);
	}

public void RemoveRole(Role role)
	{
		if(role == null)
			throw new ArgumentNullException("role");

((IList)Roles).Remove(role);
	}
}

As you can see the AddRole and RemoveRole methods provide safe access to the underlying collection. It should be noted however that these can actually be circumvented by the following cast:

((IList)Roles).Add(theRole);

So while this is a handy concept – it's not 100% foolproof!