Event Hookup Part One

 

Ever had one of those problems where you are coding outside your normal zone, but you know the answer is simple, and can’t get the syntax right on the day?

Friday was one of those days, here is the outline of my problem, I am refractoring one of my customer tests, its a windows form, and instead of having all the code within the form itself, I am moving it to a MVP layout, not a problem overall you may think, currently it has a bunch of controls, a couple of results text box’s and a process button.

So I created the view, and started creating the presenter, now the current form uses a background worker, so i wanted to move that to the tasks layer, where the actual work would be called, the presenter being responsible for pushing messages back to the view, and receiving the data and passing it on in the correct format to the task layer.

It was all going well, that tests pass until i got to the task layer, I create a background worker, an I want to hookup the progress and complete the events, now i don’t want the task interface to rely on the background worker, I may change it to a simple threading model so my ITask interface must have event, but this time I need to pass some data with the event and thats where i got suck, stupid i know but these things happen, so Sunday afternoon I decided to run up a quick spike to solve the interface event problem and see what the code will looklike.  here is my result.

first i wrote a simple task object that would implement an interface, I extracted the interface using ReSharper (one of those little used functions, but when you need it, its a real time saver)

   1: public interface ITask
   2:     {
   3:         event Task.MyEventHandler ProgressMessage;
   4:         bool LongRunningProcess();
   5:     }
   6:  
   7:     public class Task : ITask
   8:     {
   9:         public delegate void MyEventHandler(object sender, MessageEventArgs args);
  10:  
  11:         public event MyEventHandler ProgressMessage;
  12:  
  13:         public bool LongRunningProcess()
  14:         {
  15:             if (ProgressMessage != null)
  16:             {
  17:                 var args = new MessageEventArgs();
  18:                 args.Message = "hello world";
  19:                 args.MessageFlag = 1;
  20:  
  21:                 ProgressMessage.Invoke(this, args);
  22:             }
  23:             
  24:             return true;
  25:         }
  26:     }
  27:  
  28:     public class MessageEventArgs: EventArgs
  29:     {
  30:         public string Message { get; set; }
  31:         public int MessageFlag { get; set; }
  32:     }

I know its the wrong way around, but next I wrote some tests to play with the task to see if the message was passed up to my mock presenter as I wanted.

   1: using Microsoft.VisualStudio.TestTools.UnitTesting;
   2:  
   3: namespace ExamplePresenter.Tests
   4: {
   5:     [TestClass]
   6:     public class TaskTests
   7:     {
   8:         public TestContext TestContext { get; set; }
   9:  
  10:         [TestMethod]
  11:         public void Should_Raise_Event_During_Long_Running_Call()
  12:         {
  13:             mockPresenter process = CreateSUT();
  14:             process.Task.LongRunningProcess();
  15:  
  16:             Assert.IsTrue(process.ProgressEventRaised);
  17:             Assert.AreEqual("hello world", process.MessageReceived);
  18:             Assert.AreEqual(1, process.MessageFlag);
  19:         }
  20:  
  21:         private static mockPresenter CreateSUT()
  22:         {
  23:             var task = new Task();
  24:             var presenter = new mockPresenter(task);
  25:  
  26:             return presenter;
  27:         }
  28:     }
  29:  
  30:     public class mockPresenter
  31:     {
  32:         private readonly ITask _task;
  33:  
  34:         public mockPresenter(ITask task)
  35:         {
  36:             _task = task;
  37:  
  38:             _task.ProgressMessage += ProgressTaskMessage;
  39:         }
  40:  
  41:         public ITask Task
  42:         {
  43:             get { return _task; }
  44:         }
  45:  
  46:         public int MessageFlag { get; set; }
  47:  
  48:         public string MessageReceived { get; set; }
  49:  
  50:         public bool ProgressEventRaised { get; set; }
  51:  
  52:         private void ProgressTaskMessage(object sender, MessageEventArgs args)
  53:         {
  54:             MessageReceived = args.Message;
  55:             MessageFlag = args.MessageFlag;
  56:             ProgressEventRaised = true;
  57:         }
  58:     }
  59: }

Have Fun

About Duncan Butler

Trying to be a very agile software developer, working in C# with Specflow, Nunit and Machine Specifications, and in the evening having fun with Ruby and Rails
This entry was posted in Programming. Bookmark the permalink.

Leave a comment