In this artcile I’ll explain what is a singleton pattern, how to create one, and how to combine it with lazy loading technique, including de .NET version of Lazy<T>.

That’s a lot, right? Ok, I will give you something more. I have created a little project so you can see it, test it and play with it.

So, let’s not waste your time… and get rockin!

Singleton

What is it?

The singleton design pattern is the first pattern that comes to mind to any developer. It’s easy and it appears in all the developer job tests in the world. 😉

This pattern restricts a class to have only one instance, instead of creating new instances everytime you need it in a process. That’s useful in situations where your class is used to coordinate processes or it provides general utility in most part of your application.

Before aplying this pattern we have to take in account that the instance we are creating will be kept in memory during all the process, so you have to be aware for the resources it uses.

Creating our singleton

The most used code pattern to create a singleton class is something like this:

public class Repo
{
    private static readonly Repo _instance = new Repo();
    public static Repo Instance  { get { return _instance; } }

    private IEnumerable<Country> _countries; 

    private Repo() 
    { 
        Init(); 
    } 

    private void Init() {
        var remoteStorage = new MyWebService(); 
        _countries = remoteStorage.GetCountries();     
    }

    public IEnumerable<Country> GetCountries() 
    {
        return _countries;
    }
}

In this example you can see some of the traits of a singleton class:

  • The class declares a private field of its own type (Repo). That field will encapsulate the single instance of the singleton object.
  • The encapsulated private field is published with a property that usually is named Instance, Current or even Singleton.
  • The constructor is private. This will avoid manual instantiation of the class, forcing to use the single instance it provides.
  • For basic application models, we can use static fields, but you can also use any kind of dependency injector’s life cycle control you like.

In our example, we named our property as Instance. So, to use our singleton object we would type something like this:

var countries = Repo.Instance.GetCountries();

This is different from the non-singleton approach:

var countries = new Repo().GetCountries();

Singleton cases of use

A class designed using the singleton pattern gives us the advantage of not having to instance it everytime we need it. It creates its own instance the first time it’s used, and then uses the same instance in the future.

Let’s keep up with the last example. Our method gets all the countries that start with the letter we pass as parameter:

private IEnumerable<Country> GetCountriesWithLetter(string letter)
{
    var countries = new Repo().GetCountries()
         .Where(o => o.Name.UpperCase().StartsWith(letter.UpperCase()));
}

Then in our application we do this:

AllMyCustomers.ForEach(c => c.CountriesWithYourInitial = 
                     GetCountriesWithLetter(c.Name.Substring(0,1)));

This bit of code would take all the customers from AllMyCustomers list and set his CountriesWithYourInitial property with the countries with name starting with the same letter as the customer’s name. Yes, it’s a dumb example, but it does the trick… 😉

Now let’s imagine I have hundreds, if not thousands of customers. As you can see, the constructor of our Repo class calls Init() to connect to a webservice and download all the countries to keep them in a private field.

If we do this thousands of times (one per customer), our application will take hours to run, or even crash …

This is when the singleton pattern comes to the rescue… if GetCountriesWithLetter() method uses a singleton repository like this:

private IEnumerable<Country> GetCountriesWithLetter(string letter)
{
    var countries = Repo.Instance.GetCountries()
             .Where(o => o.Name.UpperCase().StartsWith(letter.UpperCase()));
}

Countries will be loaded into Repo only the first time we use it, reusing Instance in all the subsequent calls, and avoiding multiple calls to our webservice.

Lazy Loading

Lazy loading is a very commonly used technique in development. Its recommended when we have classes containing properties that are heavy to initialize and we may not need in all scenarios.

Let’s see this example:

public class Customer
{
    public string Code { get; set; }
    public string Name { get; set; }
    public IQueryable<Invoice> InvoiceList { get; set; }

    public static Customer Get(string code)
    {
        var cust = Repo.GetCustomer(code);
        cust.InvoiceList = Repo.GetCustomerInvoices(cust.Code);
        return cust;
    }
}

In this example, when we get a customer from the repository, we are also getting all his invoices, because we don’t know when we will need them and we don’t want to check if they’re there everytime.
The downside is that the operation can mean loading lots of invoices from the database or webservice and we may not need them in our process, like this:

var cust = Customer.Get(code);
Console.WriteLine(string.Format("Hello there, {0}!", cust.Name));

Wow! We loaded all the customer’s invoices only to say Hi? That’s not fair… nor efficient.

Here is when lazy loading technique comes handy. We are changing the previous example class Customer to use it:

public class Customer
{
    public string Code { get; set; }
    public string Name { get; set; }

    private IQueryable<Invoice> _invoiceList;
    public IQueryable<Invoice> InvoiceList
    {
        get
        {
            if (null == _invoiceList)
                _invoiceList = Repo.GetCustomerInvoices(this.Code);
            return _invoiceList;
        }
    }

    public static Customer Get(string code)
    {
        return Repo.GetCustomer(code);
    }
}

We changed the responsability for loading invoices from the customer to the property InvoiceList itself. This way, when we access this property, it will check wether the inner private field _invoiceList is null or not, and if it isn’t, will load countries and keep them. Then it always will return the result.

Now we can get a customer and show his name without loading invoices, but we still can access the property InvoiceList without worrying of null references:

var cust = new Customer().Get(code);
// No invoices have been loaded yet, we didn't use the property InvoiceList
Console.WriteLine(string.Format("Hello there, {0}!", cust.Name);

// Now we access the property and the invoices will get loaded...
Console.WriteLine(string.Format("   You have {0} invoices!", 
                      cust.InvoiceList.Count());

Adding some elegance with Lazy<T>

Lazy loading has been running around for ages in OOP development, so Microsoft in .NET version 4, implemented the generic class Lazy<T> to make life easier to developers.

Using this class our code look much more elegant. The result, though, is the same. Applied to our last example:

    ...

    private Lazy<IQueryable<Invoice>> _invoiceList =
        new Lazy<IQueryable<Invoice>>(() => Repo.GetCustomerInvoices(this.Code);
    public IQueryable InvoiceList
    {
        get { return _invoiceList.Value; }
    }

    ....

This code does exactly the same as the previous example, but Lazy class will take care of checking if the value has been loaded before, and if not, will run the delegate we passed it in the initial assignment. If we only want to instantiate the “lazied” class Repo, an empty constructor.

As I said before, this is only more elegant…

Ok… let’s see how we can apply this to our singleton class from our first example:

Joining efforts

We have seen what a singleton is, and how it’s created, and we saw too how to apply lazy loading to a property.

The singleton pattern is a good place to put lazy loading in practice, since it has an object that will be instantiated only one time, and most of the times can be both a resource and a time consumer that we may or may not use in our processes.

Let’s see how our singleton class would be if we apply lazy loading:

public class Repo
{

    private static readonly Lazy<Repo> _instance = new Lazy<Repo>();
    public static Repo Instance  { get { return _instance.Value; } }

    private Lazy<IEnumerable<Country>> _countries =
           new Lazy<IEnumerable<Country>>(() => new MyWebService().GetCountries());

    public IEnumerable<Country> GetCountries()
    {
        return _countries.Value;
    }
}

Nifty, isn’t it? This adds points in terms of code reading and elegance to your classes, so don’t hesitate to use it!

Demo project

I’ve prepared a little demo project with singletons, lazy loading and Lazy<T>. This way you can see how it works step-by-step, experiment and do your own tests…

You can Git Clone it at this address:

https://bitbucket.org/joanvilarino/lazysingletondemo.git

Or simply download the ZIP file from this one:

http://repo.joanvilarino.info/lazysingletondemo/downloads

Thank you for your time!!!!

Follow me

Joan Vilariño

Senior .NET Developer at Ohpen
Developer for more than 25 years and IT, gadget, mobile and electronics enthusiast working and publishing from Barcelona.
Follow me