Friday 20 November 2009

To inject or not to inject, that is the question

When trying to implement the specification and implementation for scheduling a check, I had the problem of what method to use for sending the event.
There are basically two options:
  1. Inject a Bus
  2. Use a static/well known object for sending the event.
Lets take a look at both options...

Inject a bus


When Injecting a bus (or an other service) the Host will need a variable/field that holds the implementation of the service. Somehow the real implementation should be injected into the object. Normally we will do that by using a framework like structuremap or some other Dependency Injection framework.
But we have the problem that Host is an Entity which we will not instantiate ourself, but we ask our repository. So there will be another place where we need to inject the right service and I think this will lead us to duplicate code.

Use static object


Using a static object would be much simpler. We have one object that sends all events to the right place. How the event handlers are registered depends on the architecture of the application, but basically this will be done via an Dependency Injection framework. This method is explained more deeply by Udi Dahan.

Conclusion

Injecting services into entities is just to complicated and in my opinion should be avoided.
Using static classes as services should also be avoided, because it will make testing more difficult.

So what do we use? I will choose for the static class, because it only routes the actual events to the right handler, it will be easy to implement and it will be easy to use it in tests. Other services should be non static classes so that it follows the normal object oriented philosophy.

Wednesday 18 November 2009

The host in charge or How to design software the good way.

Software design is something that can be really challenging. This becomes more clear when you are working on a project now and than, or have some very complicated software.
In the last topic I talked about the challenge of defining the scheduler and what it should schedule. I thought it was a good and easy point to start with, but it is not. I think by starting with the scheduler I want to make it much to generic and I don't want to be to generic, I just want it to do what it should do.
To identify what it should do I have to start somewhere else.

The Host.

Within NetworkMonitor hosts play an important role. A host is a network device with a networkcard and an network address.
The state of the host can be checked and set from the outside. The host itself is responsible to notify others that a new check should be scheduled, but the user should be able to schedule a check manually as well.

This above text will leas us to the following design:

The SetState and ScheduleCheck methods will have parameters, but I don't know them yet.
The idea is that when the SetState method is called, the ScheduleCheck is called automaticly.
The ScheduleCheck will fire an event (ScheduleCheckEvent) to schedule the check. The event will contain all the necesary information for others to get the right host, the right check and the right time to perform the check.
Since the host has a public ScheduleCheck methode, the user can also schedule the check whenever he likes.

The Tests

Since this is a learning project I want to start using a Test first approach. This means we start with writing tests and then write the code to let the tests pass.
I am going to use specification style testing which means I write specifications/stories about what I need to test. Here are my specifications for the Host:
Given: an Host
When : ScheduleCheck is called
Then : a ScheduleCheckEvent is raised
Given: an Host
When : the status is set via SetStatus
Then : then a ScheduleCheckEvent is raised
I tried writing specifications before, but I found it always difficult to do. These specifications are as simple as can be. The reason for this (I think) is that I want to test less than before, or made things to complex.

ok, but that is not code.. I am going to use MSpec which is a .NET project for Behaviour Driven style testing.

public class When_scheduling_a_check
{
   static Host hots;
   Establish context = () => { host = new Host("10.1.1.2"); };
   Because of = () => { host.ScheduleCheck(DateTime.Now); };
   It should_have_raised_a_ScheduleCheckEvent;
}

public class When_setting_the_status
{
   static Host hots;
   Establish context = () => { host = new Host("10.1.1.2"); };
   Because of = () => { host.SetState(State.Ok); };
   It should_have_raise_a_ScheduleCheckEvent;
}

All that I have done here are writing the When (Establish context) and Then (Because of). The actual test is still pending.
The funny code (() => {};) is part of the .NET syntax and are called lambda expressions. This makes it possible to put functions/methods inside a property to be run at a later moment.

Well thats all for today. I will have to implement this first before I continue :)

Thursday 5 November 2009

Scheduler, what to schedule?

I am thinking about the scheduler part of my NetworkMonitor. On of the things I want to do in the NetworkMonitor is to use a service layer. A service layer is a thin layer between the actual application (executable / user interface) and the domain. and it provide the supported scenarios. In case of Commands Query Seperation, it also provide the commands and their handlers.

Back to the scheduler part... I want to have a SchedulingService which provide all the possible operations for the scheduler. Since I want to use the YAGNI (You Aint Gonna Need It) approach. I only have two methods for this service:
  • Schedule something
  • Do something with the Scheduled things
As you can see this is really vague... What do I need to schedule? Do I schedule Events? Do I schedule Commands? (here commands are a domain specific thing) Do I schedule System.Action?

At this point I just don't know... I think it really depends on how generic this scheduler should be... Should I be able to schedule tasks that are not domain stuff as well? or do I choose to schedule only domain specific stuff.

The solution
Well, since I want to be YAGNI, I think I decide to schedule only domain specific tasks. When a task is scheduled and it is time to perform the task I will fire an event to let some other class know that it should be performed.
Conclusion
It is a good thing to think out loud... You get some solutions that way.