Twitter Agent – Decoupling From Dependencies
Lately I have been posting about a Twitter/Dovetail CRM integration we have been working on. Recently I made some architectural changes that I will hopefully get to in a future post. This time around I wanted to talk about how a problem with the jabber-net XMPP library led to a better more testable design.
Connection Stability
Last post I talked about how we are using XMPP to send and receive direct messages with Twitter and when Twitter’s XMPP presence is up it works great. Really well in fact. The main challenge has been keeping the connection to our Jabber server stable. The jabber-net library has an auto-reconnection issue when DNS cannot be resolved it gives up trying to reconnect. I did get some guidance from their Google Group on correcting this issue but unfortunately had already moved to a different library agsXmpp for which I was able to get a timed reconnect working.
Keeping your dependencies under control
One very useful side-effect of making the move to the agsXmpp library was a refactoring of how Twitter Agent communicates with the XMPP library.
public interface IXmppConnection { void Connect(); void Disconnect(); void SendMessage(string toJID, string messageToSend); bool IsConnected { get; } event ActionIMessage OnMessageReceived; }
Before I would set a delegate that received a library specific Message object. Refactoring towards an abstract message IMessage completely decouples our code from the XMPP library. This also affords great testability. Interaction testing was previously difficult because it was hard to mock the library specific concrete message object.
Another side-effect of thinking about all messages that enter the system as an abstract IMessage led me to re-architect how messages are processed end-to-end but I will get to that next time.
Sneaky
I snuck in the fact that Gary and I stormed up a new name for the our Dovetail CRM/Twitter integration. Twitter Agent. What do you think?