Friday, 10 October 2008

What I've got against NHibernate

Apart from being another example of too much configuration in XML? Well Billy McCafferty has summed it up for me in his article on CodeProject

Your database should be an "implementation detail" that is defined to support your domain model, not the other way around.
No it shouldn't. This is backwards for all but the largest businesses with lots of DBAs and data warehouses. This is a very arrogant developer argument to make.

It is more important to the business to be able to quickly and accuratly report about the business than to sell one more widget. Getting timely and accurate information about the widgets you've sold is more important. I know of lots of businesses who sold lots of their product and still went bust, owing to poor finanical management. Every business has to be able to manage their cash-flow at least as well as they can sell, and the database should represent this. Programmers can make the program more flexible to fit in with the best design for the business, but database design should be driven by business requirements, not programmers' whimsey.

In many, many cases both of these requirements will be in alignment, but not always. Some of your objects may need to populate and be populated from multiple tables, and whilst NHibernate can support this, it does drive developers to generate a 1-1 database model matching their entities.

And another thing, Billy doesn't hint at this, but says it explictly.

it is commonly accepted by many that ORM technologies, when used correctly, are, in fact, a silver bullet for software development
No they're not - don't be stupid. ORM technologies are a useful shortcut for developers to do less boring code, but they are not a silver bullet. They do not replace data abstraction layers, mearly form part of it. ORM is about being able to maintain the state of your objects in a database. Databases do more than just store developer's objects - how arrogant is this man?

Databases and DAL often perform complex data manipulation required by the business. Sometimes you need a process which will derive data from inputs, and you need a manageable, maintainable design pattern to implement these processes with data decorators and transformation objects. Whether you choose to put this code in NHibernate or elsewhere, then it still needs to be done. Using NHibernate doesn't remove business requirements.

Dependency Injection Frameworks

Call me crazy, but I don't get why the world has gone mad, and experienced developers are in love with DI frameworks.

Don't get me wrong - I get IoC. I can see how it helps with flexibility even if I'm not completely convinced that it reduces coupling. You're, at best, no better off in terms of coupling, but objects can be used in new abstracted ways.

I even get understand how dependency injection could potentially help this, adding another layer of abstraction on how your objects relate to each other.

What gives me the fear is that you're putting your application configuration into an XML document. That's an XML document everyone, which is going to control how your objects relate to each other; which types to create; which objects should be cast with which interfaces. In an XML document.

A document that maybe dozens of developers will be working on. A document that is very, very unlikely to contain any comments. A document which is not validated at design time, or build time, only at run-time. A document which in twelve months will be unmaintainable garbage. A document that contractors will dick with for a few weeks and then leave. Your entire application in the hands of one XML document. No.

Lots of things DI framework providers write really scare me, and I don't scare easily. Here's something from Winter4Net

Fast - handles more than 20mb configurations
Aarrrghhh! I'm a big tough man, but even I tremble when I think that my enterprise-scale application maybe in the hands of a 20mb XML document that no-one will be able to follow.

And actually, its not just mentally-large config documents. Here's what the ubiquitous Nate has to say about Ninject.
To define a conditional binding, the two fluent interfaces (binding and condition) work together. Here's an example:
Bind().To();
Bind().To().Only(When.Context.Target.HasAttribute());
What? So now I'm putting business logic into configuration? I admit that if I had to use a DI framework, then I'm attracted to Ninject if only because of the whole 'it's not an XML document'

How can we take this idea further? I know! What I'm going to invent is a really flexible configuration system which I'll process and turn into commands my CPU understands, and I'll call it F*CKING CODE!