Archive for the ‘C#’ Category

Using an Event Aggregator from StoryTeller

August 12, 2009

The StoryTeller aggregator utilizes two ways to get published events to the listeners. The first requires creating listeners that implement an

    public interface IListener<T>

    {

        void Handle(T message);

    }

 
Publishing events requires using

void SendMessage<T>(T message);

 
Setting up an event handler (listeners is pretty easy. Just implement the interface for the class. If you are using ReSharper, You get code generation for free.

The second way is to supply a specific listener object when you send a message. I removed this method from the aggregator because it would not allow me to use an Action<T> signature message.

I extracted the event aggregator from StoryTeller to use as the messaging system for my new application. Since I didn’t have that much experience with this type of pattern, I needed some feedback for the application.

The feedback that I was interested in was the wiring of the events and there cascading effects when the events are activated. Pretty much this creates an event workflow.

The events used in the aggregator are push events. You load the event with data then publish the event. The events initially seem to be weak, There isn’t much to them except for the classes them selves.

More still to come…

Extension Methods or a Closure: Why Not Both?

August 11, 2009

Lambdas can be useful for creating little utilities that can help you create more readable code. An example of creating an abstraction.

        [Test]

        public void should_use_classes_instead_of_better_stuff()

        {

            Looper.Loop(5, new Printer());

        }

 

        public class Looper

        {

            public static void Loop(int count, Printer print)

            {

                const int max_count = 5;

                for (int i = 0; i < max_count; i++)

                    print.Output();

            }

        }

 

        public class Printer

        {

            public void Output()

            {

                Console.WriteLine("Executing");

            }

        }

 
Output

Executing

Executing

Executing

Executing

Executing

 
As you can see a lot of work just to print out “Executing” string, and you may run into having to make a changes into your classes.
 
Let’s say the string printed to the console needs to change like this.
 

        [Test]

        public void should_use_classes_instead_of_better_stuff()

        {

            Looper.Loop(1, new Printer("Start"));

            Looper.Loop(5, new Printer("Middle"));

            Looper.Loop(1, new Printer("End"));

        }

 

    public class Looper

    {

        public static void Loop(int max_count, Printer print)

        {

            for (int i = 0; i < max_count; i++)

            {

                print.Output();

            }

        }

    }

 

    public class Printer

    {

        private readonly string _prefix;

 

        public Printer(string prefix)

        {

            _prefix = prefix;

        }

 

        public void Output()

        {

            Console.WriteLine("{0} Executing", _prefix);

        }

    }

Output

Start Executing

Middle Executing

Middle Executing

Middle Executing

Middle Executing

Middle Executing

End Executing

 
Now let’s get into using closures. 
 

        [Test]

        public void should_use_closures()

        {

            Action<string> print = (prefix => Console.WriteLine("{0} Executing", prefix));

 

            Action<int, Action> loop = ((count, fn) =>

            {

                for (int i = 0; i < count; i++)

                {

                    fn();

                }

            });

 

            loop(1, () => print("Start"));

            loop(5, () => print("Middle"));

            loop(1, () => print("End"));

        }

 
Output is the same as above.
 
It still is a little noisy in the parameter for print. So let’s clean this up.
 

        [Test]

        public void should_use_binding_lambda()

        {

            Action<string> print = (prefix => Console.WriteLine("{0} Executing", prefix));

 

            Action<int, Action> loop = ((count, fn) =>

            {

                for (int i = 0; i < count; i++)

                {

                    fn();

                }

            });

 

            Func<string, Action> use_printer = (prefix => () => print(prefix));

 

            loop(1, use_printer("Start"));

            loop(5, use_printer("Middle"));

            loop(1, use_printer("End"));

        }

 
This is nice abstraction. It hides the for loop from the programmer.

It still is noisy. How can we clean this up. TADA! Extension to the rescue.

    public static void Times(this int count, Action function)

    {

        for (int i = 0; i < count; i++)

        {

            function();

        }

    }

And the actual usage

[Test]

public void should_use_binding_lambda_and_extension()

{

    Action<string> print = (prefix => Console.WriteLine("{0} Executing", prefix));

 

    Action<int, Action> loop = ((count, fn) =>

    {

        for (int i = 0; i < count; i++)

        {

            fn();

        }

    });

 

    Func<string, Action> use_printer = (prefix => () => print(prefix));

 

    1.Times(use_printer("Start"));

    5.Times(use_printer("Middle"));

    1.Times(use_printer("End"));

 

}

 
Usage for all 4 iterations
 

// class objects

Looper.Loop(5, new Printer("Middle"));

//closure

loop(5, () => print("Middle"));

//binding on lambda

loop(5, use_printer("Middle"));

//extension

5.Times(use_printer("Middle"));

 
Now which one would you use?

Using lambdas for handling change

August 9, 2009

I was TDDing an Event Logger. Now the logger takes an event message and then adds a date time stamp. The way you would do it is use DateTime.Now. The problem was how to verify that the date time stamp had been added. Pass into the object a DateTimeServer object. This seemed too much. Create an object. Talk about noisy tests. Instead I just pass this object into my logger and here is some some of the logger code:

        [Test]

        public void should_add_date_time_stamps()

        {

            const string dts = "mm/dd/yyyy 00:00:00 AM";

 

            Func<string> dateTimeStamper = (() => dts);

            var logger = new EventLogger(dateTimeStamper);

            logger.Handle(OperationEstop.EStop);

            logger.Handle(OperationEstop.EStop);

 

            logger.Data().ShouldContainForEachLine(dts);

            logger.Data().Lines().ShouldEqual(2);

        }

Notice in the test ShouldContainForEachLine and Lines methods. These are extension methods. They make the test much more readable.

    public class EventLogger : IListener<OperationEstop>, 
        IListener<StatusMessage>, IListener<LoginSuccessful>,
        IListener<LoginEvent>, IListener<ScheduleLoad>,
        IListener<ScheduleLoadEvent>, IListener<SystemEvent>
    {
        private readonly StringBuilder _sb = new StringBuilder();
        private readonly Func<string> _dateTimeStamp;
 
        public EventLogger(Func<string> stamp)
        {
            _dateTimeStamp = stamp;
        }
 
        public string Data()
        {
            return _sb.ToString();
        }
 
        public void Handle(OperationEstop message)
        {
            AddDateTimeStampToEntry(message.Status());
        }
 
        //Other Handlers ...
 
        private void AddDateTimeStampToEntry(string status)
        {
            if (_sb.Length > 0)
                _sb.AppendLine();
 
            _sb.AppendFormat("{0} {1}", _dateTimeStamp(), status.Trim());
        }
    }