Want to show your appreciation?
Please a cup of tea.

Saturday, May 31, 2008

Raising Events in NMock 2.0

Neil Bourgeois posted an excellent article on this. I find myself often need EventHandler<TEventArgs> in addition to EventHandler, and also I would like to write Will(Hookup.Event(mockEvent)) because it reads more natually so easier to understand:
   1:MockEvent mockEvent = new MockEvent();
   2:Expect.Once.On(mockProvider).EventAdd("EffectiveUserChanged", Is.Anything)
   3:    .Will(Hookup.Event(mockEvent));
   4:mockEvent.Raise(mockProvider, EventArgs.Empty);
Here I added a static class Hookup and generic versions of Neil's classes.
   1:    /// <summary>
   2:    /// http://blog.gravityfree.ca/2007/03/raising-events-in-nmock-20.html
   3:    /// </summary>
   4:    /// <author>Neil Bourgeois</author>
   5:    /// <author>Kenneth Xu</author>
   6:    /// <seealso cref="MockEvent{TEventArgs}"/>
   7:    /// <seealso cref="Hookup"/>
   8:    public class MockEvent
   9:    {
  10:        private EventHandler _handler;
  11:
  12:        public void Initialize(EventHandler handler)
  13:        {
  14:            this._handler = handler;
  15:        }
  16:
  17:        public void Raise()
  18:        {
  19:            Raise(this, EventArgs.Empty);
  20:        }
  21:
  22:        public void Raise(object source, EventArgs e)
  23:        {
  24:            _handler.Invoke(source, e);
  25:        }
  26:
  27:    }
  28:
  29:    /// <summary>
  30:    /// http://blog.gravityfree.ca/2007/03/raising-events-in-nmock-20.html
  31:    /// </summary>
  32:    /// <author>Neil Bourgeois</author>
  33:    /// <author>Kenneth Xu</author>
  34:    /// <seealso cref="MockEvent"/>
  35:    /// <seealso cref="Hookup"/>
  36:    public class MockEvent<TEventArgs> where TEventArgs : EventArgs
  37:    {
  38:        private EventHandler<TEventArgs> _handler;
  39:
  40:        public void Initialize(EventHandler<TEventArgs> handler)
  41:        {
  42:            this._handler = handler;
  43:        }
  44:
  45:        public void Raise(object source, TEventArgs e)
  46:        {
  47:            _handler.Invoke(source, e);
  48:        }
  49:
  50:    }
  51:
  52:    /// <summary>
  53:    /// See BusinessContextTest for an example.
  54:    /// </summary>
  55:    /// <author>Kenneth Xu</author>
  56:    /// <seealso cref="MockEvent"/>
  57:    /// <seealso cref="MockEvent{TEventArgs}"/>
  58:    public static class Hookup
  59:    {
  60:        public static IAction Event(MockEvent mockEvent)
  61:        {
  62:            return new MockEventHookup(mockEvent);
  63:        }
  64:
  65:        public static IAction Event<TEventArgs>(MockEvent<TEventArgs> mockEvent)
  66:            where TEventArgs : EventArgs
  67:        {
  68:            return new MockEventHookup<TEventArgs>(mockEvent);
  69:        }
  70:
  71:        /// <summary>
  72:        /// http://blog.gravityfree.ca/2007/03/raising-events-in-nmock-20.html
  73:        /// </summary>
  74:        /// <author>Neil Bourgeois</author>
  75:        /// <seealso cref="MockEvent"/>
  76:        /// <seealso cref="MockEventHookup{TEventArgs}"/>
  77:        private class MockEventHookup : IAction
  78:        {
  79:            private readonly MockEvent mockEvent;
  80:
  81:            public MockEventHookup(MockEvent mockEvent)
  82:            {
  83:                this.mockEvent = mockEvent;
  84:            }
  85:
  86:            public void Invoke(Invocation invocation)
  87:            {
  88:                EventHandler handler = invocation.Parameters[0] as EventHandler;
  89:                if (handler == null)
  90:                    throw new Exception("Unknown event handler type: " + invocation.Parameters[0].GetType());
  91:                mockEvent.Initialize(handler);
  92:            }
  93:
  94:            public void DescribeTo(TextWriter writer)
  95:            {
  96:                // do nothing
  97:            }
  98:        }
  99:
 100:        /// <summary>
 101:        /// http://blog.gravityfree.ca/2007/03/raising-events-in-nmock-20.html
 102:        /// </summary>
 103:        /// <author>Neil Bourgeois</author>
 104:        /// <seealso cref="MockEvent{TEventArgs}"/>
 105:        /// <seealso cref="MockEventHookup"/>
 106:        private class MockEventHookup<TEventArgs> : IAction
 107:            where TEventArgs : EventArgs
 108:        {
 109:            private readonly MockEvent<TEventArgs> mockEvent;
 110:
 111:            public MockEventHookup(MockEvent<TEventArgs> mockEvent)
 112:            {
 113:                this.mockEvent = mockEvent;
 114:            }
 115:
 116:            public void Invoke(Invocation invocation)
 117:            {
 118:                EventHandler<TEventArgs> handler = invocation.Parameters[0] as EventHandler<TEventArgs>;
 119:                if (handler == null)
 120:                    throw new Exception("Unknown event handler type: " + invocation.Parameters[0].GetType());
 121:                mockEvent.Initialize(handler);
 122:            }
 123:
 124:            public void DescribeTo(TextWriter writer)
 125:            {
 126:                // do nothing
 127:            }
 128:        }
 129:    }
 130:

Thursday, May 08, 2008

Logging the SQL generated by NHibernate

Having used Hibernate for many years but relatively new to NHibernate, I though logging SQL executed by NHibernate would be a simple log4net configuration task, but only to find out it is not as straightforward as I thought. The problem is mainly due to a specious solution on Internet here (Update: Dave correct the post, Thanks!) and here. The correct logger to use is NHibernate.SQL, NOT NHibernate.Loader.Loader. And you need DEBUG level instead of INFO. What's confusing was that the NHibernate.Loader.Loader does log all the SELECT statements but not for UPDATE statement. The XML section below works for me.
  <log4net>
    <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date - %message%newline"/>
      </layout>
    </appender>
    <logger name="NHibernate.SQL" additivity="false">
      <level value="DEBUG" />
      <appender-ref ref="ConsoleAppender" />
    </logger>
  </log4net>

Find the mouse position in WndProc

I had a need to know the mouse position when subclassing the ComboBox (will blog this part later). Googled for it and the best I can get is a post in VB.NET news group. I was hoping a method somewhere in the .Net can easily do this, but I couldn't find it. For now, I have this method below to do the work.
        /// <summary>
        /// Extract the mouse position from mouse related
        /// <see cref="Message">.
        /// </summary>
        /// <param name="mouseMessage"></param>
        /// <returns>Position of the mouse</returns>
        public static Point GetMousePosition(Message mouseMessage)
        {
            int lParam = mouseMessage.LParam.ToInt32();
            int x = (lParam & 0xFFFF);
            int y = (int)(lParam & 0xFFFF0000 >> 16);
            return new Point(x, y);

        }