UPDATE:
Rob was kind enough to discuss on that issue. What I understand is that he thinks this increases complexity for now, since he doesn’t want to have multiple handlers, but spam service is quite enough.
Thanks Rob!
I know, I know. I am talking about Events a lot, but the reason for that is: I love them. They provide hell of a great way to decouple your design, and improve flexibility.
After reading Rob Conery’s Twitter about implementing subkismet for oxite, I decided to take a look at since I did it once, too. I take a look at it, unfortunately it wasn’t like what I expected from Rob but definitely he is a great guy!
My way of handling this issue will be based on events and the code is in BlogSharp codebase
As an illustration, I will work on comment adding process, where a user comes and write comments.
There is a problem with Rob’s implementation, IMHO. Spam control should not be part of comment adding process. Putting it right into Create method of CommentController will viloate the SRP and OCP as there may be some other controls on the comment as well, such as check for duplication, or flood, etc. You may also want to notify the author of the post whenever a comment is added.
All these issues can be easily addressed by using events.
public class PostService : IPostService
{
#region IPostService Members
public void AddPost(IPost post);
public void AddComment(IPostComment comment)
{
var commentAdding = new CommentAddingEventArgs(comment);
this.CommentAdding.Raise(this,commentAdding);
if (commentAdding.Cancel)
return;
Repository<IPostComment>.Instance.Add(comment);
var commentAdded = new CommentAddedEventArgs(comment);
this.CommentAdded.Raise(this,commentAdded);
}
public void RemoveComment(IPostComment comment);
public void RemovePost(IPost post);
public IPost GetPostById(int id);
public IPost GetPostByFriendlyTitle(string friendlyTitle);
#endregion
#region IPostService Members
public event EventHandler<IPostService, PostAddingEventArgs> PostAdding = delegate { };
public event EventHandler<IPostService, PostAddedEventArgs> PostAdded = delegate { };
public event EventHandler<IPostService, PostRemovingEventArgs> PostRemoving = delegate { };
public event EventHandler<IPostService, PostRemovedEventArgs> PostRemoved = delegate { };
public event EventHandler<IPostService, CommentAddingEventArgs> CommentAdding = delegate { };
public event EventHandler<IPostService, CommentAddedEventArgs> CommentAdded = delegate { };
#endregion
}
Then, you let your plugins add themselves as event handler for particular action, and act accordingly.
PS: Raise is an extension method (thanks Sidar Ok for warning me about the ugliness of previous implementation)
public static class EventHandlerHelpers
{
public static void Raise<TSource,TEventArgs>(this EventHandler<TSource,TEventArgs> @event,TSource source,TEventArgs eventArgs)
{
if(@event!=null)
@event(source, eventArgs);
}
}
18ad995c-8b1f-4b14-9fa1-7b7055608d09|1|2.0
events, patterns