Code Review Singleton Pattern Issues

Posted by: Steven Smith, on 02 Feb 2012 | View original | Bookmarked: 0 time(s)

One of my applications relies on a singleton pattern to create a single instance of a server which processes requests from many different ASP.NET handlers.  It is created using pretty much standard Singleton code:

public static Context CreateContext()
{
    return CreateContext(new ConfigurationFileSettings());
}

Recently, this server needed to be made aware of whether requests were coming into it via SSL or standard HTTP.  The solution that was checked in (and which worked and passes local tests) is to create a new property of Context called IsSecureConnection, and to allow this to be passed into its public constructor like this:

public Context(ISettings settings, 
    bool isSecureConnection)
{
    this.Settings = settings;
    this.IsSecureConnection = isSecureConnection;
}

This is pretty much classic Dependency Injection and most of the time is what I would consider the right approach to the problem.  However, in this case it fails to take into account how this object is used, because of the fact that it’s using a Singleton.  And in this case nothing ever calls this constructor anyway – the actual solution that was applied instead only made use of the IsSecureConnection property (which was read/write).

The client code in the ASP.NET handlers that invokes the Context class looks like this (before adding any support for SSL):

Context engineContext = Context.CreateContext();

After adding support for SSL, this code became:

Context engineContext = Context.CreateContext();
engineContext.IsSecureConnection = isSecureConnection;

Looks fine, right?  Run it through some tests – things behave as expected.  SSL requests get routed to the Context object with IsSecureConnection = true.  Regular HTTP requests get routed with IsSecureConnection = false.  Stick a fork in it and ship it…

Global State and Static / Singleton Objects

The problem of course is that many different ASP.NET handlers are talking to the same exact instance of Context.  In this particular application, this is taking place tens of times each second.  So if you imagine that 49 requests come in during a given second over HTTP and 1 comes in over HTTPS, it’s quite likely that while the Context has had its IsSecureConnection property set to one value, it’s in the middle of processing another request.

The other issue here is that whether or not a given request is using SSL is a lower level concern to the Context object which is in essence a request manager.  The only call that the handlers ever send to Context is something like this:

Response myResponse = engineContext.GetResponse(_myParamsDTO);
Recommendation Singleton pattern, and even less so of static objects and methods.  They’re extremely difficult to test and prone to problems with synchronization and multiple threading like the one shown here.  In development, things that work just fine often end up failing in production under load.  If you think your application really needs a static or singleton, consider whether or not this is a premature optimization, and build the application using standard object creation semantics until you have proof that this will not be capable of meeting your design’s needs.


Advertisement
Free Agile Project Management Tool from Telerik
TeamPulse Community Edition helps your team effectively capture requirements, manage project plans, assign and track work, and most importantly, be continually connected with each other.
Category: ASP.NET | Other Posts: View all posts by this blogger | Report as irrelevant | View bloggers stats | Views: 382 | Hits: 28

Similar Posts

  • New Entity Framework Feature CTP for VS2010 Beta 2 more
  • Business Apps Example for Silverlight 3 RTM and .NET RIA Services July Update: Part 25: ViewModel more
  • September's Toolbox Column Now Online more
  • Your code via NDepend more
  • Canvas gets a Spark more
  • July's Toolbox Column Now Online more
  • Principles, Patterns, and Practices of Mediocre Programming more
  • Form and List 05.00.03 released more
  • June's Toolbox Column Now Online more
  • 8 techniques to find problems in your unit tests within 30 seconds more

News Categories

.NET | Agile | Ajax | Architecture | ASP.NET | BizTalk | C# | Certification | Data | DataGrid | DataSet | Debugger | DotNetNuke | Events | GridView | IIS | Indigo | JavaScript | Mobile | Mono | Patterns and Practices | Performance | Podcast | Refactor | Regex | Security | Sharepoint | Silverlight | Smart Client Applications | Software | SQL | VB.NET | Visual Studio | W3 | WCF | WinFx | WPF | WSE | XAML | XLinq | XML | XSD