Implementing IUpdatable (Part 2)
After spending time creating my own caches of reflection data I found the NHibernate type information to be more complete and faster. Go figure. At this point I am using the SessionFactory's GetClassMetadata and GetCollectionMetadata to return IClassMetadata and ICollectionMetadata interfaces. So far this has given me every piece of runtime information I need and means that I don't need to do any nasty (and potentially fragile) walking through the property interface of the context object. Whew...
So to refactor my GetResource and CreateResource calls. GetResource is easy. GetResource passes in the query and the full type name (though the full type name may be missing in some cases). The query it passes it must resolve to a single result. That means I can simply execute the the query and if it returns more or less than one result, return an error. Once I have the result I can just check it against the full type name (if it was passed in) and return the value.
CreateResource is a bit more complicated. The IClassMetadata allows me to call their Instantiate method to create a new instance of the class but the new instance is not initialized with any data. Most notably, the missing detail is a key. In the case of many entities, this is fine (e.g. if zero ID is a valid "new" entity). But in others the key needs to be specified. (Customer in the Northwind database is an example of this.) The problem is that we have to keep a reference to the new objects so that when ADO.NET Data Services asks us to set properties, get properties and save, we have to have the object in the Session. But we can't add it to the Session with an invalid key. What to do? My solution for now is a local cache of objects that are not ready to be saved (only really happens with newly created objects). When we are ready to save, we'll just add it to the Session then (when its either valid or we'll throw an exception because its invalid).
Now a quick mention of GetProperty and SetProperty. These are both pretty easy as the IClassMetadata includes a similar method to set and get properties. The only wrinkle is that if you try and set a key using the GetProperty/SetProperty, the keys are not in the list of properties. Because of this I just checked to see if the property is part of the key and set the key instead, if its not part of the key we can just set or get the property. Now that we have the basic part of the interface complete its down to the hard parts. But that's for the next part!