Thursday, August 19, 2010

Using Lazy class for Singleton object creation

Lazy class in .NET 4.0 provides support for lazy initialization of objects. This can be used as a helper class for handling multi-threaded access to shared resources that are expensive to create. To keep from creating these shared resources multiple times I use to have a Singleton class implementation with checks or locks for thread synchronization.


The singleton implementation looked like:

public class Singleton where T : new()

{

public static T Instance

{

get

{

if (___instance == null)

{

lock (___syncLock)

{

___instance = Activator.CreateInstance();
}

}

return ___instance;

}

}

static object ___syncLock = new object();

static T ___instance;

}

[TestMethod]
public void Singleton_object_creation_test_should_return_a_single_instance_only()

{

Guid employeeGuid = Guid.NewGuid();

Employee singletonEmployee1 = Singleton.Instance;

singletonEmployee1.Name = "Prajeesh Prathap";

singletonEmployee1.Id = employeeGuid;

Employee singletonEmployee2 = Singleton.Instance;

Assert.IsNotNull(singletonEmployee1, "Singleton implementation returned a null instance!!!");


Assert.IsNotNull(singletonEmployee2, "Singleton implementation returned a null instance!!!");

Assert.IsTrue(singletonEmployee1.Id == singletonEmployee2.Id);

}



By using the Lazy class, the above code can be replaced as

[TestMethod]
public void Lazy_keyword_usage_will_create_object_on_demand_and_return_a_threadsafe_instance_that_can_be_shared()

{

Guid employeeGuid = Guid.NewGuid();

Lazy lazyInitializer = new Lazy(() => new Employee { Id = employeeGuid, Name = "Prajeesh" });


Assert.IsFalse(lazyInitializer.IsValueCreated, "Object instance found!!!, lazy initialization failed");

Employee lazyEmployee1 = lazyInitializer.Value;

Assert.IsTrue(lazyInitializer.IsValueCreated, "Failed to initialize instance!!!");
Assert.IsNotNull(lazyEmployee1);
Employee lazyEmployee2 = lazyInitializer.Value;

Assert.IsTrue(lazyEmployee1.Id == lazyEmployee2.Id);

}

No comments: