When designing code that can be unit tested, a primary concern is breaking any external dependencies that your class may have. One option is to use constructor or property injection to allow the objects to be replaced by stubs or mocks in the unit tests. However, this could become cumbersome, especially if there are a number of dependencies.
A simple alternative is to create a class that handles the creation of objects. For production code, the class needs to simply return an object of the type requested. We’ll create two methods, one that uses the default constructor and one that allows the caller to provide a constructor.
public static class ObjectConstructor
{
public static T GetObject<T>() where T : new()
{
return GetObject(() => new T());
}
public static T GetObject<T>(Func<T> constructor)
{
return constructor();
}
}
Now, we need to add a way to replace the object created with a stub or a mock for unit tests. We can do this by maintaining a list of objects. When an object is requested, it will first look in that list. Otherwise, it will build the object using the constructor.
public static class ObjectConstructor
{
static SortedList<string, object> _objects = new SortedList<string, object>();
public static T GetObject<T>() where T : new()
{
return GetObject(() => new T());
}
public static T GetObject<T>(Func<T> constructor)
{
var typeName = typeof(T).FullName ?? string.Empty;
if (!_objects.ContainsKey(typeName))
return constructor();
return (T)_objects[typeName];
}
public static void AddObject<T>(T obj)
{
var typeName = typeof(T).FullName ?? string.Empty;
_objects.Add(typeName, obj);
}
}
Finally, we’ll also add some additional methods for removing objects. We also want to make sure that our class is thread safe, so we to also need add some locks to the code.
public static class ObjectConstructor
{
static SortedList<string, object> _objects = new SortedList<string, object>();
static Object lockObj = new object();
public static T GetObject<T>() where T : new()
{
return GetObject(() => new T());
}
public static T GetObject<T>(Func<T> constructor)
{
lock (lockObj)
{
var typeName = typeof(T).FullName ?? string.Empty;
if (!_objects.ContainsKey(typeName))
return constructor();
return (T)_objects[typeName];
}
}
public static void AddObject<T>(T obj)
{
lock (lockObj)
{
RemoveObject<T>();
var typeName = typeof(T).FullName ?? string.Empty;
_objects.Add(typeName, obj);
}
}
public static void RemoveObject<T>()
{
lock (lockObj)
{
var typeName = typeof(T).FullName ?? string.Empty;
if (_objects.ContainsKey(typeName))
_objects.Remove(typeName);
}
}
public static void ClearObjects()
{
lock (lockObj)
{
_objects = new SortedList<string, object>();
}
}
}
To use the class, create your objects using a call to the GetObject method. Below are examples of how to use both the default constructor and how to provide the constructor as input.
var accountRepository1 = ObjectConstructor.GetObject<AccountRepository>(); var accountRepository2 = ObjectConstructor.GetObject(() => new AccountRepository(parm));
In the setup for your unit test, add your mocked object to the ObjectConstructor. Then, the subsequent call to GetObject will return the mocked object.
ObjectConstructor.AddObject(mockedAccountRepository);
Since only the test code will add objects, all your production objects will be created using their constructors. So, you now have a reusable class for creating your objects and allowing an easy way to handle dependency injection.




