Mike Nichols - Son of Nun Technology

February 2007 Entries

Castle Makes Me Happy

There are some good points to the new Enterprise Library Validation Block but for the life of me I don't understand the API that locks you into using generic type parameters to just get a validator (the non-generic method the generic one simply wraps is INTERNAL....).
Anyways, I am late to the party as usual and was stoked to see the Castle .Validation component. As usual it is easy to use and does just what it should ... So I am off to try to make sure it'll do what I need.
See Hammet's post for info.

Divine Event Handling

There is a better way of doing this I am sure, but I needed to make sure that handlers that were assigned to a control's events were kept in reverse order.

For example, I have a control on the page that has an event that is being 'listened' to by the page for navigation instructions. A number of child controls are on the page and will also need to be listening to this event as well. Now, the other controls are dynamically loaded and will be attaching their event handlers as they are done so...but that means that their handlers will not be fired until AFTER the page handler is fired.

So basically, I needed to create a way to enforce that the first handler attached will always be the last one in the invocation list order. so i drummed up a little utility to do exactly this...The first method name I came up with was RegisterEvent_FirstRegisteredAlwaysLast, but that made me think of...

But many that are first shall be last; and the last shall be first. For the kingdom of heaven is like unto a man that is an householder, which went out early in the morning to hire labourers into his vineyard.
(Mat 19:30-20:1)

So I couldn't resist a better method name...

 

    public class EventUtil

    {

        /// <summary>

        /// Keeps the first event registered LAST on invocation order and the most recent event added is FIRST.

        /// </summary>

        /// <typeparam name="TEventArgs"></typeparam>

        /// <param name="eventObj"></param>

        /// <param name="eventHandlerToRegister"></param>

        /// <returns></returns>

        public static EventHandler<TEventArgs> RegisterEvent_KingdomOfHeaven<TEventArgs>(EventHandler<TEventArgs> eventObj, Proc<object, TEventArgs> eventHandlerToRegister)

                where TEventArgs : System.EventArgs

        {

            if (eventObj == null)

            {

                eventObj += new EventHandler<TEventArgs>(eventHandlerToRegister);

                return eventObj;

            }

 

            Delegate[] handlers = eventObj.GetInvocationList();

            eventObj = null;

            eventObj += new EventHandler<TEventArgs>(eventHandlerToRegister);

 

            foreach (Delegate handler in handlers)

            {

                eventObj += new EventHandler<TEventArgs>((EventHandler<TEventArgs>)handler);

            }

 

            return eventObj;

        }

    }

Now I can just stick this in my control

:

 public void RegisterEvent(Proc<object, EventArgs<int>> eventHandler)

            {

                Event1 =EventUtil.RegisterEvent_KingdomOfHeaven<EventArgs<int>>(Event1,eventHandler);

 

            }

Automatically Embedding NHibernate Resource Files

This would actually work on any kind of file type I suppose...

Each time I add a .hbm.xml NHibernate mapping file to a project it is easy to forget to select "Embedded" under build action. Since I don't directly create my mappings but rather have NAnt hydrate them during my builds I wanted to automate the declaration to embed them automatically.

On a whim, I went into the .csproj file and deleted all the referenced to any .hbm.xml files and then replaced them with this :

<ItemGroup>
<EmbeddedResource Include="NHibernateMappings\*.hbm.xml" />
</ItemGroup>

Now, each time my NAnt script runs and squirts the mappings into my project folder they are automatically embedded and it's one less thing to remember upon running within VS during debugging.

Not sure this is legitimate but I haven't had any problems.

Growing Pains In OR/M - Part 4

I wasn't planning on blogging tonight but I was answering some questions in NHibernate's forum and I see a lack of understanding of a crucial principle in embracing OR/M tools.

I have been trying to log what I have learned and am learning in effectively using an OR/M to improve development. Specifically, I am using NHibernate...if some of what I say doesn't apply to other OR/M's that's just because I am still wet behind my ears :)

Here are the previous posts:

RELAX AND JUST BUILD YOUR DOMAIN

This is really just a restatement of Part I where I was trying to explain the leap from a relational thought process toward an object-oriented thought process. Simply stated, don't sit down and start with your table structure and then see if your ORM can do it. I have seen myself fall into two traps with this erroneous approach:

  1. This results in a disease I am privvy to that I call Tool Malignment Syndrome. Basically, this is when you pick a tool (such as an OR/M) and as soon as you get it you start to write code to make it do things it isn't good at. Just because you might need to do that some day. This syndrome's cousin is Not-Invented-Here.
  2. Another syndrome I am prone to...Elaborate Solution Reflux. This is the one that sends someone deep into the bowels of a tool's source-code or API to make it do something that could be solved with a more obvious solution.

I recall writing generic implementations of Custom Types in NHibernate when a Component would have been much simpler and prudent. I learned alot and it has actually been useful on a couple of situations, but the time spent on it may have been better used. This was partly because of my learning curve (I am wondering when that will end) and also because I always was haunted by the "what if..." in programming (YAGNI). A key principle helped alleviate this for me, though, and that is simply writing my domain and pushing back the details of OR/M implementation to support it until the last possible moment. There will definitely be times when i have to write some quick tests to see how NHibernate will accomodate things like complicated queries, but this isn't the driving force behind ANY design decision in my domain. If it were, I'd opt for a different OR/M. This is drawn from the Domain Driven Design camp that insists that the Domain is the driver for the application.

A question came up tonight that had a picture of three tables and then a mapping file that was trying to accomodate the table structure. I realize sometimes this is just the way things are (legacy) but mostly it is just trying to swim upstream. My recommendation over and over is to write your classes, build your API and THEN use the power of your OR/M to represent that in the database. I have noticed that since adapting this style of programming my speed of completing meaningful and useable modules has at least DOUBLED.

Okay...back to work...