Jarloo

Menu

Lazy Loading in C#

C# comes with built-in Lazy loading for those of us who are … well Lazy.  The .NET function is simply called Lazy and here is one easy way to use it in your projects.

Suppose you have a List of customers and each customer had a list of purchase orders associated with that customer.  When loading the customer you would need to goto your PurchaseOrders table and load the purchase orders associated with that customer.  This gets to be quite a bit of data if you have thousands of customers each with hundreds of purchase orders.

Lazy loading to the rescue!  Lazy loading will let you defer loading the purchase orders on each of your customers until those purchase orders are needed.  This means that your program will load faster cause it only needs to load the customers and not the purchase orders, but that it will take a small performance hit each time the operator of your program views a customers purchase orders.  Now considering that the operator would never view all the purchase orders of the thousands of customers Lazy loading will save the operator time and resources.

Here is an example, I will explain below, but pay special attention to the Customer Class’s PurchaseOrder property, it’s where the magic is.

Customer Class

using System;
using System.Collections.Generic;

namespace Jarloo
{
    public class Customer
    {
        public int Id { get; private set; }
        public Lazy<List<PurchaseOrder>> PurchaseOrders { get; private set; }

        public Customer(int id)
        {
            Id = id;
            PurchaseOrders = new Lazy<List<PurchaseOrder>>(() => PurchaseOrderFactory.GetOrders(Id));
        }
    }
}

Purchase Order Class

using System;

namespace Jarloo
{
    public class PurchaseOrder
    {
        public int Id { get; set; }
        public string ProductName { get; set; }
        public int Quantity { get; set; }
        public DateTime Timestamp { get; set; }
    }
}

Purchase Order Factory

using System;
using System.Collections.Generic;

namespace Jarloo
{
    public class PurchaseOrderFactory
    {
        public static List<PurchaseOrder> GetOrders(int id)
        {
            //Normally you could query the db here to get the details
            //instead in this example we return the same stuff per customer id

            Console.WriteLine("Creating Purchase Orders");

            List<PurchaseOrder> orders = new List<PurchaseOrder>();

            for (int i = 0; i < 20; i++)
            {
                PurchaseOrder o = new PurchaseOrder();
                o.Id = i;
                o.ProductName = "Test";
                o.Quantity = 5 + i;
                o.Timestamp = DateTime.Now;
                orders.Add(o);
            }

            return orders;
        }
    }
}

Main Method

using System;

namespace Jarloo
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            Customer cust = new Customer(10);

            Console.WriteLine("IsValueCreated=" + cust.PurchaseOrders.IsValueCreated);

            int count = cust.PurchaseOrders.Value.Count;

            Console.WriteLine("IsValueCreated=" + cust.PurchaseOrders.IsValueCreated);

            Console.ReadLine();
        }
    }
}

So when we query our customer object and check the IsValueCreated property it will return “false”. Then once we access it in anyway such as getting the count of objects, the Lazy type will invoke the function we gave it which is our factory, and the factory will return the purchase orders. So when we check the IsValueCreated again it is now “true” since the initialization of our PurchaseOrders property has occurred.

There are several other overrides you can explore if this one on the Lazy<> type doesn’t meet your needs.

Categories:   Code

Tags:  ,

Comments

Sorry, comments are closed for this item.