views:

90

answers:

2

I'd like to know what you think of the following design options.

I have an 'AgendaController' (.NET MVC project) which handles user actions like viewing their agenda, making appointments, etcetera. When a user makes an appointment, the appointment is saved in a database. Then, there is a 'secondary' task that has to be done, in this case sending a message to the user (whether this is a text sms, email, or something else is not relevant). I can implement this in three different ways:

  1. I could simply add a call directly in the controller action, something like messageService.SendNewAppointmentMessage(data). Which is fine, I guess, though it does clutter up the controller action a bit. Specifically, if, because of some future requirement some other action needs to be done (for example, logging although not a good example) I'd get yet another call to some logger class.

  2. I could declare a static event in the AgendaController, OnAppointmentMade, and create a MessageService that subscribes to this event. Then, when an appointment is saved, the event is fired and the actual message sending handled somewhere else. I could have more classes subscribe to this event if those requirements come up. This way, the controller action stays very clean, and all 'secondary tasks' are performed somewhere else.

  3. I could use a custom attribute on the controller action, [SendNewAppointment], and send the message in the OnActionExecuting method of that attribute. This follows the MVC design nicely I guess, but I don't necessarily like the Attributes clutter: I'd have an Authorize, AcceptVerbs, ActionName, SendNewAppointment, etc etc attribute on a single controller action.

Which design is preferred? Which one is certainly a no-go? I have a slight preference for the second design, although I wonder if one should (mis)use events for this. I'd really like to hear your opinions!

A: 

To be honest, all 3 options are perfectly viable....

I would personally go with the 2nd approach. Its cleaner and allows you to handle the message sending in another class.

It also means your Message sending class could be re-used by other objects.

James
A: 

Personally, I slightly preper the first option, since it's the most testable one.

The second option is also good, but I dislike the idea of static events, since everything static is harder to test (I'm not saying impossible, just harder).

Udi Dahan recently posted an article on Domain Events that resembles your second option quite a lot, and he's a smart guy so it's worth to take into consideration. Personally, I'd still prefer a variation where the event broker (essentially a Mediator) is passed in as an instance, but the general idea remains.

Mark Seemann
Interesting link. I'll give it a good read. I agree with your statement that everything static is harder to test, though I do think that this is one of those cases were this might actually not be the case (the event can simply be ignored, for instance). I also like the first one, but it also means that I'd have to mock the MessageService in my unit tests. Which is fine, but it simply implies more work: I have to mock an AgendaRepository, UserRepository - they do the db calls for saving agenda and user data - and then also the MessageService.
Razzie