I am working on updating a legacy application that is absolutely rife with Singleton classes. A perfect example would be the SnmpConnector class:
public SnmpConnector
{
public static IEnumerable<string> HostIpAddresses
{
...
}
private static SnmpConnector instance;
public static SnmpConnector Instance
{
if (instance == null)
instance = new SnmpConnector();
return instance;
}
private SnmpConnector()
{
foreach (string IpAddress in HostIpAddresses)
{
...
}
}
...
}
The goal of this update is to increase testability of the codebase, and as such I want to get rid of the Singletons. I've already abstracted away the data source of the SnmpConnector to either get data from a test database or from querying a live server:
public interface ISnmpDataSource
{
public DataTable MacTable
{
get;
private set;
}
public DataTable PortTable
{
get;
private set;
}
...
}
public TestSnmpDataSource : ISnmpDataSource
{
public FileInfo DataSource
{
get;
private set;
}
...
}
public SnmpDataSource : ISnmpDataSource
{
public List<string> HostIpAddresses
{
get;
private set;
}
...
}
public SnmpConnector
{
public SnmpConnector(ISnmpDataSource DataSource)
{
...
}
...
}
Now, I'm trying to test these components and running into the problem that probably caused SnmpConnector to be a Singleton in the first place: it takes an ungodly amount of time to test the SnmpDataSource. It turns out that fetching the MAC table and Port table from live switches takes somewhere between 10 and 20 seconds. I've already written 13 unit tests for this particular class, so it takes over two minutes for just these tests to complete. As annoying as this is, it gets worse once these updates get published to our original codebase. With this new refactoring, there is nothing stopping a programmer from creating and discarding an SnmpDataSource repeatedly.
Now, the data from these tables is largely static; the old Singleton and the new SnmpDataSource both maintain a cache that was only updated every four hours. Will I have to make SnmpDataSource a Singleton to prevent this problem?