Saturday, September 20, 2008

Photosynth Fun

I was inspired by the Photosynth session at REMIX. It's a fascinating technology, not so much for what it currently delivers, which is very cool, but it's future promise. I had a very interesting discussion with a chap after the session, who's name I didn't get. He was saying that Photosynth is obviously only a stepping stone on the way to 3D model generation from photos. The practical applications for such a technology are far reaching. Just think of the implication for robots that are able to create a hi-fidelity model of their surroundings. Or for game designers who will be able to reproduce real environments several orders of magnitude faster than they can today. My favorite sci-fi scenario is the possibility of combining the 3D models with 3D printers to quickly and easily reproduce any artifact.

In the meantime, back on Earth, I've had a play with Photosynth myself. Here's my first attempt, a 'synth' of my Dining room.

dining-room-photosynth

http://photosynth.net/view.aspx?cid=8ecec4eb-1f1b-428e-9a81-642579315ac3

You can see my current stack of computer books, my old Dell (but with spanking new Das Keyboard), some awful paintings I did at school, my old LPs, the piano (a nineteenth century Bluthner) and my Eastman John Pisano guitar.

Suteki Shop at REMIX

Scott Guthrie was kind enough to show a screen shot of the first commercial Suteki Shop implementation at REMIX UK last week. For anyone who was at the keynote speech, I was the 'Mike' he mentioned. I was lucky enough to have a couple of conversations with him during the conference. He's a very down to earth and approachable guy.

jump-the-gun

Jump the Gun are a legendary Modernist fashion shop in the North Lanes of Brighton. Brighton has, of course, been the spiritual home of the mods ever since their heyday in the 60's so I'm really proud that they've chosen Suteki Shop as their e-commerce platform. It's a great example of a long tail business and they hope to become the world's leading on-line retailer of mod clothing.

We're planning to go live this week and I'll be making a big announcement when that happens, so watch this space!

Wednesday, September 17, 2008

Form validation with MVC Framework Preview 5

The latest release of the MVC Framework, Preview 5, has some nice additions for doing form based validation. Scott Guthrie has an in-depth blog post here describing these features, so please read that if you haven't already.

Very briefly the validation framework has four elements:

  1. Model binders based on the IModelBinder interface. You can override the default binders by setting properties on the static ModelBinders class.
  2. New UpdateModel methods on Controller that bind a given model to the Request.Form. The model binders are also used to bind request form values to action parameters.
  3. A ModelStateDictionary that maintains the results of a binding operation. This is maintained in the ViewData.
  4. Updated HtmlHelper input control renderers (like TextBox)  and a new HtmlHelper ValidationMessage extension method. These work together to show validation messages on the form by reading the ModelStateDictionary that's contained in the ViewData.

On the whole it's a nicely thought out framework. I especially like the ability to slot in your own implementations of IModelBinder. But there are other things I don't like so much, especially the way the UpdateModel methods on the controller work. In fact I think that the base controller class is getting far too god-like, with too many concerns over and above executing action methods. Having all these controller methods makes actions hard to test and the whole framework less 'plugable'.

In his post, Scott shows how to implement a validation rules engine that you can plug in to your domain entities. I really don't like this approach, it relies on the developer always remembering to call a particular validation method after setting properties. That or an over intimate relationship between the entity and the ORM.

I like to put validation in my domain entity's property setters. It just seems the most natural and obvious place for them.I've blogged about this before, but today I want to show how it can work very nicely with most of the preview 5 framework.

Have a look at this property of my domain entity:

public virtual string Code
{
    get { return code; }
    set
    {
        code = value.Label("Code").IsRequired().Value;
    }
}

IsRequired is an extension method that raises a ValidationException if value is null or empty. The ValidationException it raises has a nice message "You must enter a value for Code". Now if we simply use the UpdateModel method out-of-the-box like this:

[AcceptVerbs("POST")]
public ActionResult Edit(int id, FormCollection form)
{
    var centre = centreRepository.GetById(id);
    try
    {
        UpdateModel(centre, new[]{"Code", "NetscapeName"});
        centreRepository.SubmitChanges();
        return RedirectToAction("Edit", new { id });
    }
    catch (Exception)
    {
        return RenderEditView(centre);
    }
}

We get this message on the page when we forget to enter a Code:

Validation1

Not the nice message that I was expecting. The reason for this is that UpdateModel has a try-catch block that catches Exception and inserts its own message: "The value '<input value>' is invalid for property '<property name>'" whatever the exception may have been. That's not really very useful. Here's a section of the code from the MVC Framework source (I think I'm allowed to put this on my blog):

foreach (var property in properties) {
    string fieldName = property.Key;
    PropertyDescriptor propDescriptor = property.Value;
    IModelBinder converter = ModelBinders.GetBinder(propDescriptor.PropertyType);
    object convertedValue = converter.GetValue(ControllerContext, fieldName, propDescriptor.PropertyType, ViewData.ModelState);
    if (convertedValue != null) {
        try {
            propDescriptor.SetValue(model, convertedValue);
        }
        catch {
            // want to use the current culture since this message is potentially displayed to the end user
            string message = String.Format(CultureInfo.CurrentCulture, MvcResources.Common_ValueNotValidForProperty,
                convertedValue, propDescriptor.Name);
            string attemptedValue = Convert.ToString(convertedValue, CultureInfo.CurrentCulture);
            ViewData.ModelState.AddModelError(fieldName, attemptedValue, message);
        }
    }
}

Having a blanket catch like that around the property setter is not a good idea. What if some unexpected exception happened? I wouldn't know about it, I'd just assume that there was some type conversion error. Also there's no way to get your own exception message into the ModelState at this stage. Scott's blog post shows a work-around where you populate the ModelState at a later stage in the controller, but I want my framework to do that for me.

OK, so I don't like the UpdateModel method on the controller, I'd much rather have my validator injected by my IoC container. To this end I've implemented my own ValidatingBinder:

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Web.Mvc;
using Suteki.Common.Extensions;
namespace Suteki.Common.Validation
{
    public class ValidatingBinder : IValidatingBinder
    {
        private readonly List<IBindProperties> propertyBinders;
        public ValidatingBinder() : this(new IBindProperties[0])
        {
        }
        public ValidatingBinder(params IBindProperties[] propertyBinders)
        {
            this.propertyBinders = new List<IBindProperties>(propertyBinders);
        }
        public List<IBindProperties> PropertyBinders
        {
            get { return propertyBinders; }
        }
        public virtual void UpdateFrom(object target, NameValueCollection values)
        {
            UpdateFrom(target, values, new ModelStateDictionary(), null);
        }
        public virtual void UpdateFrom(object target, NameValueCollection values, ModelStateDictionary modelStateDictionary)
        {
            UpdateFrom(target, values, modelStateDictionary, null);
        }
        public virtual void UpdateFrom(object target, NameValueCollection values, string objectPrefix)
        {
            UpdateFrom(target, values, new ModelStateDictionary(), objectPrefix);
        }
        public virtual void UpdateFrom(
            object target, 
            NameValueCollection values, 
            ModelStateDictionary modelStateDictionary, 
            string objectPrefix)
        {
            UpdateFrom(new BindingContext(target, values, objectPrefix, modelStateDictionary));
        }
        public virtual void UpdateFrom(BindingContext bindingContext)
        {
            foreach (var property in bindingContext.Target.GetType().GetProperties())
            {
                try
                {
                    foreach (var binder in propertyBinders)
                    {
                        binder.Bind(property, bindingContext);
                    }
                }
                catch (Exception exception)
                {
                    if (exception.InnerException is FormatException ||
                        exception.InnerException is IndexOutOfRangeException)
                    {
                        bindingContext.AddModelError(property.Name, bindingContext.AttemptedValue, "Invalid value for {0}".With(property.Name));
                    }
                    else if (exception.InnerException is ValidationException)
                    {
                        bindingContext.AddModelError(property.Name, bindingContext.AttemptedValue, exception.InnerException);
                    }
                    else
                    {
                        throw;
                    }
                }
            }
            if (!bindingContext.ModelStateDictionary.IsValid)
            {
                throw new ValidationException("Bind Failed. See ModelStateDictionary for errors");
            }
        }
        /// <summary>
        /// IModelBinder.GetValue
        /// </summary>
        public virtual object GetValue(
            ControllerContext controllerContext, 
            string modelName, 
            Type modelType, 
            ModelStateDictionary modelState)
        {
            if (controllerContext == null)
            {
                throw new ArgumentNullException("controllerContext");
            }
            if (String.IsNullOrEmpty(modelName))
            {
                throw new ArgumentException("Cannot be null or empty", "modelName");
            }
            if (modelType == null)
            {
                throw new ArgumentNullException("modelType");
            }
            if (IsBasicType(modelType))
            {
                return new DefaultModelBinder().GetValue(controllerContext, modelName, modelType, modelState);
            }
            var instance = Activator.CreateInstance(modelType);
            var request = controllerContext.HttpContext.Request;
            var form = request.RequestType == "POST" ? request.Form : request.QueryString;
            UpdateFrom(instance, form); 
            return instance;
        }
        private static bool IsBasicType(Type type)
        {
            return (type.IsPrimitive ||
                type.IsEnum ||
                type == typeof(decimal) ||
                type == typeof(Guid) ||
                type == typeof(DateTime) ||
                type == typeof(string));
        }
    }
}

There are a few things to note about this class. The first is that the actual property binding itself is delegated to a list of property binders that implement the IBindProperties interface. This means I can chain as many specialized property binders that I like and have the IoC container inject them into the ValidatingBinder. All the information needed by the binding operation; the target entity, the form values and the ModelStateDictionary are contained in a BindingContext instance that also knows how to get a particular property value from the form values. I've also implemented IModelBinder.GetValue so that it will work with action property binding as well.

The most important thing for this discussion is the try-catch block in the UpdateFrom method. Note that I look for specific exception types. If I can find a ValidationException I pass that to the ModelStateDictionary which means that the message I want will be shown on the form.

OK, so here's my action method, but now it's using the ValidatingBinder:

[AcceptVerbs("POST")]
public ActionResult Edit(int id, FormCollection form)
{
    var centre = centreRepository.GetById(id);
    try
    {
        validatingBinder.UpdateFrom(centre, form, ViewData.ModelState);
        centreRepository.SubmitChanges();
        return RedirectToAction("Edit", new { id });
    }
    catch (ValidationException)
    {
        return RenderEditView(centre);
    }
}

When we attempt an update without a code we now get this nice validation exception:

Validation2

I hope this post doesn't come across as too much of a criticism of the validation infrastructure in preview 5.  Most of it I like. I have to have a specialized binder in any case for binding NHibernate entities when I'm updating an object graph, so it's very satisfying that the new control renderers can be made to work with it without too much sweat.

Tuesday, September 16, 2008

Resolving arrays with Windsor

Here's a class that takes an array of ISubThing as a constructor parameter:

public class Thing
{
    readonly List<ISubThing> subThings = new List<ISubThing>();
    public Thing(params ISubThing[] subThings)
    {
        this.subThings.AddRange(subThings);
    }
    public List<ISubThing> SubThings
    {
        get { return subThings; }
    }
}

Now can you guess what happens if we resolve this using MicroKernel? I naively thought that all my registered ISubThing services would get passed to the constructor, but in fact you get a handler exception saying that the container cannot find anything to supply the subThings property:

[Test, ExpectedException(typeof(HandlerException))]
public void DoesNotResolveArraysByDefault()
{
    var kernel = new DefaultKernel();
    kernel.Register(
        Component.For<Thing>(),
        Component.For<ISubThing>().ImplementedBy<First>(),
        Component.For<ISubThing>().ImplementedBy<Second>(),
        Component.For<ISubThing>().ImplementedBy<Third>()
        );
    var thing = kernel.Resolve<Thing>();
}

Hammett explains the problem here (check the comments) and shows an ArrayResolver that can be added to the kernel to enable the behaviour I was expecting. Now this test works:

[Test]
public void ShouldResolveArrayOfDependencies()
{
    var kernel = new DefaultKernel();
    kernel.Resolver.AddSubResolver(new ArrayResolver(kernel));
    kernel.Register(
        Component.For<Thing>(),
        Component.For<ISubThing>().ImplementedBy<First>(),
        Component.For<ISubThing>().ImplementedBy<Second>(),
        Component.For<ISubThing>().ImplementedBy<Third>()
        );
    var thing = kernel.Resolve<Thing>();
    Assert.That(thing.SubThings.Count, Is.EqualTo(3));
    Assert.That(thing.SubThings[0], Is.InstanceOfType(typeof(First)));
    Assert.That(thing.SubThings[1], Is.InstanceOfType(typeof(Second)));
    Assert.That(thing.SubThings[2], Is.InstanceOfType(typeof(Third)));
}

As Hammett explains in his post, this is a dangerous thing to add to your container, because the implementation he gives doesn't check for circular dependencies. Say we have this class which implements ISubThing:

public class Circular : ISubThing
{
    public Thing Thing { get; private set; }
    public Circular(Thing thing)
    {
        this.Thing = thing;
    }
}

As you can see it takes a Thing in its constructor, so we'd expect a circular reference exception to be raised by the container. But this test shows that doesn't happen:

[Test]
public void DoesNotDiscoverCircularDependencies()
{
    var kernel = new DefaultKernel();
    kernel.Resolver.AddSubResolver(new ArrayResolver(kernel));
    // a circular reference exception should be thrown here
    kernel.Register(
        Component.For<Thing>(),
        Component.For<ISubThing>().ImplementedBy<Circular>()
        );
    // this crashes the test framework!
    // var thing = kernel.Resolve<Thing>();
}

Instead, if you un-comment the last line the test framework crashes.

Andrey Shchekin has a great series of posts comparing different IoC containers:

http://blog.ashmind.com/index.php/2008/09/08/comparing-net-di-ioc-frameworks-part-2/

It's interesting that only StructureMap actually resolves array dependencies out of the box. It's such a nice feature with endless applications that I would have expected it to be more common. Interestingly MEF (which is trying very hard not to be seen as an IoC container) does this as one its core competencies. but then being able to discover a collection of components that supply a particular service is almost an essential requirement of its stated role as a plug-in framework.

Sunday, September 14, 2008

ALT.NET UK (un)conference

I had a lot of fun yesterday at the ALT.NET UK (un)conference. Ian, Alan and Ben do a great job organizing it and they managed to raise a lot more sponsorship money this time which meant that they could hire a larger venue, Conway Hall.

Friday night was spent suggesting sessions. There was some kind of dance thing going on in the main hall and it was difficult to hear what was going on at times but there was still a huge range of ideas put forward. Later we retired to the pub where I had some great conversations. I especially enjoyed hearing Sebastien Lambla talking about his open rasta RESTfull web development framework. I've heard him presenting about it before, but maybe it needed a couple of pints of Czech larger for it to make sense. I'm awaiting its release with some anticipation now.

Saturday morning kicked off with a 'park bench'. I'm not sure what the subject was since I spent a little too long enjoying the hotel breakfast and complementary FT. BTW good choice of hotel Ben! I think it was something like 'what does ALT.NET mean?' There was a suggestion that we needed a list of principles somewhat like the Agile movement, but I have to agree with Alan here; I think it would be a bad idea. I didn't get to the bench, but to me ALT.NET is really simple, it means building a community around .NET development that is not controlled by Microsoft. You don't need ALT.Java because that market is diverse and competitive enough that no single vendor is perceived as the single source of tools and guidance. But that is exactly the case with .NET development. The majority of .NET shops simply look to Microsoft for both. ALT.NET provides a convenient label for the .NET community to coalesce ideas around. This is good for .NET development in general, but also good for Microsoft itself.

The first session I attended in the morning was covering ORM use. We had a great discussion of the pros and cons of NHibernate vs Linq-to-SQL vs EF. I ranted a good deal about how any ORM in the .NET space had to have a LINQ provider. We also had a good discussion around repository patterns, where LINQ fits into the specification pattern and DTOs. We stayed in the same room to talk about Multi-tenanting. There were three or four people present who were actively involved in developing multi-tenanted applications so this was a very useful discussion. It mostly revolved around database sharding vs multiple-database patterns and security concerns.

During lunch we had a very interesting and wide ranging chat about IoC containers that then became a discussion on the horrors of sharepoint development.

Ian Cooper lead a very good session on Domain Driven Development in the afternoon. I've heard Ian talk about DDD several times now, but I always seem to learn something new. I would love to see a project that he'd worked on.

This brings me to a suggestion for future ALT.NET conferences. There are some excellent conversations but I do think that it would help if more people brought laptops and we had some projectors available where we could demonstrate real code. Talking about code is very difficult without having examples in front of you. I don't mean that we should be giving presentations, but that at least we should all come prepared to show off something of what we're doing. Of course this is problematic with the commercial code that most of us work on, but being able to fire up Visual Studio (or notepad Peter :) and show rather than tell would be a huge advantage. So Ian, Alan and Ben, if you want to know what to do with the sponsorship money next time: projectors!

Thursday, September 11, 2008

Today's WTF

This a real email that a colleague received just now:

"Many thanks for your regular updates I have now spoken to XXX (who was very charming).  He has confirmed our suspicion that <WTF system> in its current state is unable to handle student names that are reserved SQL keywords such as Min, Max etc" 

Thanks to Iain for matching cartoon:

exploits_of_a_mom

http://xkcd.com/327/

Tuesday, September 09, 2008

MVC Framework Validation

I really enjoy Stephen Walther's blog. It's a fantastic mine of information on the MVC Framework. Recently he's been talking about Validation: here and here. He describes using validation attributes on his entities and then providing a validation framework that reads the entities and checks form post values against them. OK, that's my one-sentence summary, it's really quite sophisticated and you should read his posts because if you want to take that kind of approach his solution is well worked out.

I don't like it though. Call me old-fashioned, but I really like to have validation expressed in the domain entity itself. It seems a more DDD friendly way of doing things. Property setters, or constructor arguments, should throw exceptions if the values passed to them fail validation rules. Entities should enforce business rules rather than relying on convention to make them work. With Stephen's method it's easy to set an incorrect value on an entity. You have to explicitly invoke his framework in order for the attributes to be evaluated.

Here's an example from Suteki Shop.  Please ignore the LINQ-to-SQL nastiness, but here's a partial class for my Category entity. In the OnNameChanging partial method (that's triggered when the Name property is set) I'm using my validation extensions that I described here. If the value is not present (null or empty) a ValidationException is raised. You can't set Name to an empty or null string from anywhere in the application without this being checked.

using Suteki.Common;
using Suteki.Common.Validation;

namespace Suteki.Shop
{
    public partial class Category : IOrderable, IActivatable
    {
        partial void OnNameChanging(string value)
        {
            value.Label("Name").IsRequired();
        }

        public bool HasProducts
        {
            get
            {
                return Products.Count > 0;
            }
        }
    }
}

A common concern with this method is that the validation rules get triggered when an entity is retrieved from the database. Fortunately LINQ-to-SQL sets the backing field rather than the property setter so this doesn't happen. Any decent ORM will allow you to do the same thing.

The next issue is binding. You need a way of gathering any validation exceptions and presenting them all back to the user. I do this with a custom ValidatingBinder. The Category controller Update action looks like this:

public ActionResult Update(int categoryId)
{
    Category category = null;
    if (categoryId == 0)
    {
        category = new Category();
    }
    else
    {
        category = categoryRepository.GetById(categoryId);
    }

    try
    {
        ValidatingBinder.UpdateFrom(category, Request.Form);
    }
    catch (ValidationException validationException)
    {
        return View("Edit", EditViewData.WithCategory(category)
            .WithErrorMessage(validationException.Message));
    }

    if (categoryId == 0)
    {
        categoryRepository.InsertOnSubmit(category);
    }

    categoryRepository.SubmitChanges();

    return View("Edit", EditViewData.WithCategory(category).WithMessage("The category has been saved"));
}

The ValidatingBinder itself is mostly taken from the excellent MVCContrib. The main thing it does differently is collecting any ValidationExceptions raised from property setters and bundling them all into an uber ValidationException that is raised back to the controller.

I've recently updated ValidatingBinder to implement the new  IModelBinder interface from Preview 5. Very simple to do, and I'll write more about this soon. Here's the ValidatingBinder code:

using System;
using System.Collections.Specialized;
using System.Reflection;
using System.ComponentModel;
using System.Text;
using System.Data.Linq.Mapping;
using Suteki.Common.Extensions;

namespace Suteki.Common.Validation
{
    public class ValidatingBinder
    {
        public static void UpdateFrom(object target, NameValueCollection values)
        {
            UpdateFrom(target, values, null);
        }

        public static void UpdateFrom(object target, NameValueCollection values, string objectPrefix)
        {
            var targetType = target.GetType();
            var typeName = targetType.Name;

            var exceptionMessage = new StringBuilder();

            foreach (var property in targetType.GetProperties())
            {
                var propertyName = property.Name;
                if (!string.IsNullOrEmpty(objectPrefix))
                {
                    propertyName = objectPrefix + "." + property.Name;
                }
                if (values[propertyName] == null)
                {
                    propertyName = typeName + "." + property.Name;
                }
                if (values[propertyName] == null)
                {
                    propertyName = typeName + "_" + property.Name;
                }
                if (values[propertyName] != null)
                {
                    var converter = TypeDescriptor.GetConverter(property.PropertyType);
                    var stringValue = values[propertyName];
                    if (!converter.CanConvertFrom(typeof(string)))
                    {
                        throw new FormatException("No type converter available for type: " + property.PropertyType);
                    }
                    try
                    {
                        var value = converter.ConvertFrom(stringValue);
                        property.SetValue(target, value, null);
                    }
                    catch (Exception exception)
                    {
                        if (exception.InnerException is FormatException ||
                            exception.InnerException is IndexOutOfRangeException)
                        {
                            exceptionMessage.AppendFormat("'{0}' is not a valid value for {1}<br />", stringValue, property.Name);
                        }
                        else if (exception.InnerException is ValidationException)
                        {
                            exceptionMessage.AppendFormat("{0}<br />", exception.InnerException.Message);
                        }
                        else
                        {
                            throw;
                        }
                    }
                }
                else
                {
                    // boolean values like checkboxes don't appear unless checked, so set false by default
                    if (property.PropertyType == typeof(bool) && property.HasAttribute(typeof(ColumnAttribute)))
                    {
                        property.SetValue(target, false, null);
                    }
                }
            }
            if (exceptionMessage.Length > 0)
            {
                throw new ValidationException(exceptionMessage.ToString());
            }
        }
    }
}

You can find all this code in Suteki Shop as usual.

Monday, September 08, 2008

Managed Extensibility Framework: Why?

Sometimes... no often... I'm quite dumb. I've been skimming through posts about the MEF thinking that people were talking about the Entity Framework (Microsoft Entity Framework :). I only realised that it was something new today. So what is it. Well it looks like an IoC container, but the spin is that it's different from other IoC containers because it's primarily aimed at providing an extensibility model; a common way for applications and frameworks to load types from dropped-in assemblies. This is from the CodePlex MEF site:

"MEF presents a simple solution for the runtime extensibility problem. Until now, any application that wanted to support a plugin model needed to create its own infrastructure from scratch. Those plug-ins would often be application-specific and could not be reused across multiple implementations.

MEF provides a standard way for the host application to expose itself and consume external extensions. Extensions, by their nature, can be reused amongst different applications. However, an extension could still be implemented in a way that is application-specific. Extensions themselves can depend on one another and MEF will make sure they are wired together in the correct order (another thing you won't have to worry about).

MEF offers a set of discovery approaches for your application to locate and load available extensions.

MEF allows tagging extensions with additional metadata which facilitates rich querying and filtering"

The thing is, although they're selling it as a plug-in framework, it does look very much like any other IoC container,  so it's odd that they're making the plug-in pitch when they could be providing a generic IoC framework. There doesn't seem to be anything about it which precludes using it in the general IoC role, except that they say it's not optimised for that.

So it begs the question: are the MEF team suggesting that we support two IoC frameworks in our applications? One for plug-in extensibility, the other to support internal component based architecture?

It seems to me that it would not be very hard to provide an IoC container that can successfully cover both these requirements. I haven't tried it, but I imagine it would be quite simple to provide a facility for Windsor to load assemblies from a file location, for example.

This one is going to run and run...

Tuesday, September 02, 2008

What's up with Linq to NHibernate?

With my current clients I'm building an MVC Framework application using NHibernate. I love NHibernate. Like all the best frameworks it just works for most common scenarios. I'm a new user, but I've been able to get up to speed with it very quickly. The power and flexibility of the mapping options make it easy to use with the legacy database that we're lumbered with. But the best thing about it though, is that it's built from the ground up for Domain Driven Development. This means it's possible to build a finely grained domain model unencumbered by data access concerns.

Seriously, if you're building .NET enterprise level business software and you haven't considered using NHibernate (or a competing ORM) you missing out on a huge productivity win.

Any ORM targeting .NET has to support Linq. Here the NHibernate story's not so good at the moment. The coding phenomena that is Ayende kicked off the first Linq to NHibernate implementation a while back. It was originally part of his Rhino Tools project and layered the Linq implementation on top of the NHibernate criteria API. This has now been moved to the NHibernate contrib project. The source is here:

http://sourceforge.net/projects/nhcontrib/

I've been using this in my current project, it works but only with the most straightforward queries. Anything tricky tends to fail and I've tended to go through a process of trial and error to find the right patterns. The problem seems to be mostly around the criteria API. It doesn't support a lot of the features that Linq requires, especially nested queries.

Recently a new NHibernate.Linq project has been started in the NHibernate trunk that takes a different approach. The authors are building SQL directly from the expression tree which obviously gives a lot more flexibility. The intention is to also to convert HQL to an expression tree thus having a single uniform query translation.

This is very exciting for NHibernate but there's going to be a hiatus while the new implementation evolves.

Thanks to Tuna Toksöz for the info.

Monday, September 01, 2008

Vote For Me! (again)

Voting has opened for this year's Developer Developer Developer Day at Microsoft's UK Headquarters near Reading. You can vote for the sessions you want to see here:

http://www.developerday.co.uk/ddd/votesessions.asp

I've put forward a couple of talks:

Why do I need an Inversion of Control Container   (Style: Presentation - Level: 100)
Inversion of Control (IoC) containers such as Unity Windsor and Structure Map are a hot topic in the Microsoft Development world. What are they and why is there such a buzz about them? How will they help me build better applications? Join me on a trip to an parallel universe of application architecture where I show how IoC containers at last make component oriented software development a reality.

This will be an updated version of the talk I gave at last year's DDD. I'll try and compress the 'why' and have a little more of the 'what' this time.

Using an Inversion of Control Container in a real world application   (Style: Presentation - Level: 200)
Going beyond an initial introduction to IoC containers, this talk shows their use in an open source eCommerce application, Suteki Shop. I will show how the IoC container helps us write component oriented software and can significantly simplify both our architecture and code. This will include a look at some nice techniques such as generic repositories, using IoC containers with the MVC Framework and how they can help us host services.

A more in-depth look at how an IoC container helps with a real world application. I'm really looking forward to showing off the generic repository pattern and WCF integration in this one. The problem is going to be cramming everything in.