Skip to main content

A problem commonly seen is how to properly use the Singleton pattern within the lifetime of an ASP.NET application.

[Source](https://adeneys.wordpress.com/2011/06/01/singleton-patterns-for-asp-net/ "Permalink to Singleton Patterns for ASP.NET")

# Singleton Patterns for ASP.NET

Update 13th June 2011: Thanks to Damian Kulik who left a comment on this post
pointing out that the classic singleton pattern I show below is not thread safe
and provided a link to a great article showing a few options for creating a
thread safe singleton in C#. I've updated the code examples for the classic
singleton pattern to use a thread safe singleton pattern.

Many of you are probably aware of the Singleton pattern. This code pattern
allows creating a single instance of an object and ensure there is only ever one
instance of it as well as providing centralised access to the single instance.
This pattern is useful in many cases such as loading expensive data from a data
store into memory and caching it, or tracking state inside an application.

The problem I sometimes see people having with this pattern is to do with the
lifetime of an ASP.NET application.

#### Classic Singleton Pattern

First of all, the classic singleton pattern. This pattern ensures you only have
a single instance of your object and provide a global mechanism to retrieve the
object.

**Original non-thread-safe singleton pattern**

    namespace Demo
    {
        public class Singleton
        {
            private static Singleton m_instance = null;

            public static Singleton Instance
            {
                get
                {
                    if (m_instance == null)
                    {
                        m_instance = new Singleton();
                    }

                    return m_instance;
                }
            }

            private Singleton()
            {
            }
        }
    }

**Thread-safe singleton**

    namespace Demo
    {
        public sealed class SafeSingleton
        {
            private static readonly SafeSingleton m_instance = null;

            public static SafeSingleton Instance
            {
                get
                {
                    return m_instance;
                }
            }

            static SafeSingleton()
            {
                m_instance = new SafeSingleton();
            }

            private SafeSingleton()
            {
            }
        }
    }

Note how the constructor is private? That means only this class can create
instance of this class, which is done through the static `Instance` property.

This pattern is good when you have data which transcends a request or session
and really should be tied to the application. Something like a settings object
which only needs to read the settings once and can then cache the data.

In a Sitecore project, if you were to create a settings object which read it's
data from the Sitecore context database then you'd also need to include a way to
refresh the data upon publish in case the items you've read the settings from
have changed.

To achieve this all you need to do is separate the reading of the settings into
a method and subscribe to the `publish:end` event and reread the settings.

**Original non-thread-safe settings singleton**

    using System;
    using Sitecore;

    namespace Demo
    {
        public class Settings
        {
            private static Settings m_instance = null;

            public int PostCount
            {
                get;
                protected set;
            }

            public static Settings Instance
            {
                get
                {
                    if (m_instance == null)
                    {
                        m_instance = new Settings();
                    }

                    return m_instance;
                }
            }

            private Settings()
            {
                Load(this, new EventArgs());
                Sitecore.Events.Event.Subscribe("publish:end", new EventHandler(Load));
            }

            protected void Load(object sender, EventArgs args)
            {
                var settings = Context.Database.GetItem("/sitecore/content/settings");
                PostCount = int.Parse(settings["post count"]);
            }
        }
    }

**Thread-safe settings singleton**

    using System;
    using Sitecore;

    namespace Demo
    {
        public sealed class SafeSettings
        {
            private static readonly SafeSettings m_instance = null;

            public int PostCount
            {
                get;
                private set;
            }

            public static SafeSettings Instance
            {
                get
                {
                    return m_instance;
                }
            }

            static SafeSettings()
            {
                m_instance = new SafeSettings();
            }

            private SafeSettings()
            {
                Load(this, new EventArgs());
                Sitecore.Events.Event.Subscribe("publish:end", new EventHandler(Load));
            }

            private void Load(object sender, EventArgs args)
            {
                var settings = Context.Database.GetItem("/sitecore/content/settings");
                PostCount = int.Parse(settings["post count"]);
            }
        }
    }

#### Singleton per Request Pattern

The issue with the classic singleton pattern for most ASP.NET developers is to
do with the lifetime of an ASP.NET application. A classic singleton pattern
stores the reference to the singleton object in a static variable. This static
variable will exist as long as the application which contains it does. And in
ASP.NET the application lives in the application pool. A new application doesn't
get created for each request as many developers might expect. The application
lives for a duration much longer than a single request. So if you create a
singleton it is the same object cross request and cross session.

Recently I stumbled upon a very nice solution to this issue. The [singleton per
request pattern][1]. This is a variation on the classic singleton pattern. The
singleton instance instead of being stored in a static variable is stored in the
`HttpContext`'s `Items` property. This means the singleton will only live as
long as the current request because we get a new `HttpContext` object for every
request.

    using System.Web;

    namespace Demo
    {
        public class RequestSingleton
        {
            private const string KEY = "RequestSingleton";

            public static RequestSingleton Instance
            {
                get
                {
                    if (HttpContext.Current.Items[KEY] == null)
                    {
                        HttpContext.Current.Items[KEY] = new RequestSingleton();
                    }
                    return HttpContext.Current.Items[KEY] as RequestSingleton;
                }
            }

            private RequestSingleton()
            {
            }
        }
    }

This pattern is good when we have data we want to store that is only relevant
for the current request. For example, in a Sitecore instance we might detect
certain conditions in the request begin pipeline that we need to persist for a
control (or rules engine component) later in the request.

#### Singleton per Session Pattern

This pattern is a slight variation on the above Singleton per Request pattern.
In this pattern I want my singleton object to be tied to the session so it lasts
for multiple requests, but only for the current user.

All I need to do to the above pattern is store my singleton object in session
rather than the `HttpContext` `Items` property.

    using System.Web;

    namespace Demo
    {
        public class SessionSingleton
        {
            private const string KEY = "SessionSingleton";

            public static SessionSingleton Instance
            {
                get
                {
                    if (HttpContext.Current.Session[KEY] == null)
                    {
                        HttpContext.Current.Session[KEY] = new SessionSingleton();
                    }
                    return HttpContext.Current.Session[KEY] as SessionSingleton;
                }
            }

            private SessionSingleton()
            {
            }
        }
    }

This pattern is good when I have user specific data I need to store in the
singleton such as what their quicklinks are or what theme colour they chose.

#### Access to Global Objects

So what benefit does the Singleton per Request and Singleton per Session
patterns carry over just accessing the global objects directly? In this case the
global objects I'm referring to is the `HttpContext` `Items` object and the
`Session` object. They are global cause we can gain access to them from anywhere
in our application through `HttpContext.Current.Items` and
`HttpContext.Current.Session`.

This issue with global objects is it's very difficult to determine what is
changing the object. The singleton patterns shown here centralise access to the
singleton object. There is only a single way to get that object and access it's
members. This is much safer and leads to more easily maintainable code.

Another benefit this pattern holds over direct access to the global objects is
strongly typed access to the data. Both the `Items` and `Session` objects are a
string-object dictionary. Every time you get an object out of those objects you
need to cast it to the proper type. But having centralised access to the data we
can simply provide strongly typed access to the data, only needing to provide
the casting in a single location.

[1]: http://dotnetslackers.com/Community/blogs/simoneb/archive/2006/08/21/The-ASP.NET-Singleton_2D00_per_2D00_Request-pattern.aspx