Implement a Factory Design Pattern using C#

Implement a Factory Design Pattern using C#

In this tutorial, you will learn the factory design pattern and implement a factory design pattern using C# to create objects of similar types dynamically.

Contact me

Find the GitHub repository of this tutorial at https://github.com/shamim-akhtar/tutorial-factory-design-pattern.

Introduction

Sometimes, you may need to instantiate a derived object of a base class whose type is unknown at compile time. The factory design pattern comes in handy in such situations. 

Using this pattern, we can instantiate a derived class type at runtime based on a creation criterion. We achieve this instantiation by defining a method that allows this object creation via a Singleton object.

Definition

A factory design pattern is a creational pattern. It uses a factory method to construct objects without knowing their class types. 

Why named a Factory Design Pattern?

In software development, analogous to an actual factory, a factory represents a software object that creates new objects of similar behaviour on-demand. This on-demand creation happens by calling a factory method.

For example, you can have a factory class called GameObjectFactory with static methods to create other game objects like a Player, an Enemy, a Gun, a Bullet or Abilities.

The latter classes might have complex constructions that make obtaining an instance of that specific class difficult. The Factory, in this case, takes care of the object’s complex configuration (for example, adding to an object pool, adding to the physics engine, adding to separate render-bins, assigning different layers, and so on) and returns a reference to the created object.

How to implement a Factory Design Pattern?

In a factory design pattern, you create an object, called the Factory, whose primary purpose is to make other objects of similar behaviour. By doing so, you avoid the problem of complex object instantiation by keeping them at a central place.

Note that the factory method doesn’t have to create new instances all the time. It can also return existing objects from a cache or from another source.

Factory Design Pattern using C# Reflection

What is C# Reflection

Reflection is a mechanism to get type and metadata information in C#. It provides metadata on types at runtime. You can use Reflection to:

  • dynamically create an instance of a given type,
  • bind the type to an existing object, or 
  • get the type from a current object and invoke its methods or access its fields and properties

The classes that give access to the metadata of a running program are in the System.Reflection namespace.

The System.Reflection namespace contains classes that allow obtaining information about an application and dynamically adding types, values, and objects. The classes in the System.Reflection namespace, together with System.Type enable you to obtain information about loaded assemblies and the types defined within them, such as classes, interfaces, and value types. You can also use Reflection to create type instances at run time and to invoke and access them.

We can use Reflection in the following cases:

  • When you are required to view or use attribute information at runtime.
  • When you need to examine various types in an assembly and instantiate these types.
  • When you require late binding to methods and properties
  • When you require creating new types at runtime and then performs some tasks using those types.

The Factory Code

using System; using System.Collections.Generic; using System.Reflection; public class CObjectFactory<T> where T: class { // The dictionary to hold the key value pairs // for the typename and type for T and all // types for subclasses derived from T private Dictionary<string, Type> mObjectTypes = new Dictionary<string, Type>(); // The singleton instance. private static readonly CObjectFactory<T> instance = new CObjectFactory<T>(); // public property to get the Singleton instance. public static CObjectFactory<T> Instance { get { return instance; } } // the private constructor. // Here we create the dictionary. private CObjectFactory() { Assembly assem = Assembly.GetAssembly(typeof(T)); Type[] types = assem.GetTypes(); foreach (Type type in types) { if ( type.IsClass && // only if class !type.IsAbstract && // only if not abstract (type == typeof(T) || // the base class. type.IsSubclassOf(typeof(T))) // all subclasses ) { mObjectTypes.Add(type.Name, type); } } } // The public method to create // instances of an object of type T or any // subclass of T. public T Create(string objectType) { if(!mObjectTypes.ContainsKey(objectType)) { Console.WriteLine("Invalid type for CObjectFactory"); return null; } Type type = mObjectTypes[objectType]; T inst = (T)Activator.CreateInstance(type); return inst; } }
Code language: C# (cs)

Applying the Factory Code to Create Objects

We will now use the above generic CObjectFactory to create objects are runtime. As an example, we define the following problem.

You are creating a game that provides a reward for daily login. You also allow a daily spin of a wheel that rewards the player based on the spin’s outcome.

Once the player is in the game, the player can play mini-quests of other mini-games. The player can also interact with other game objects in the scene based on what they interact. You can reward the player or unlock new levels. Every such action that the player does in the game is called an Activity. Your job is to keep track of all these activities and save them to the local device when the player quits the game.

Next time, when the player relaunches the game, you will have to load these activities from the local device’s storage and then recreate all the activities and show them as the player’s progress or an activity log.

For this tutorial, we will have the following activities.

The class hierarchy of Activities.

Let’s create the above classes. For now, we will keep the classes simple. In my following tutorial, I will show how to save and load these objects at runtime to and from JSON files.

public class CActivity { protected string type; protected string name; public string Type { get { return type; } set { type = value; } } public string Name { get { return name; } } public CActivity() { type = this.GetType().Name; } } public class CActivityWithTineStamp : CActivity { private string time; public DateTime Time { get { return System.DateTime.Parse(time); } set { time = value.ToString(); } } public CActivityWithTineStamp() : base() { Time = System.DateTime.Now; } } public class CActivityDailyLogin : CActivity { public CActivityDailyLogin() : base() { } } public class CActivityDailySpin : CActivity { private int reward = 0; public int SpinReward { get { return reward; } set { reward = value; } } public CActivityDailySpin() : base() { } } public class CActivityWithResponses : CActivityWithTineStamp { [System.Serializable] public struct Response { int id; string value; } private List<Response> mResponses = new List<Response>(); public List<Response> Responses { get { return mResponses; } } public CActivityWithResponses() : base() { } } public class CActivityWithDuration : CActivityWithTineStamp { float duration = 0.0f; public float DurationInseconds { get { return duration; } set { duration = value; } } public CActivityWithDuration() : base() { } } public class CActivityWithLocation : CActivityWithDuration { [System.Serializable] public struct Point3 { float x; float y; float z; } private Point3 pos; public Point3 Position { get { return pos; } set { pos = value; } } public CActivityWithLocation() : base() { } } public class CActivityMiniGame : CActivityWithDuration { string miniGameName; public string MiniGameName { get { return miniGameName; } set { miniGameName = value; } } public CActivityMiniGame() : base() { } }
Code language: C# (cs)

Create an activity using the CObjectFactory.

We can now use our generic CObjectFactory to create an instance of any derived class from the above activity classes based on the type name shown below.

CActivity act1 = CObjectFactory<CActivity>.Instance.Create("CActivityMiniGame"); CActivity act2 = CObjectFactory<CActivity>.Instance.Create("CActivityDailySpin");
Code language: C# (cs)

The power of the Factory Design Pattern is not directly measurable from the above example code. In my following tutorial, I will create instances of activity at runtime based on a JSON file that contains an array of activities. You will then realize the true potential of the Factory Design pattern for dynamic object instantiation.

Read My Other Tutorials

  1. Implement A* Pathfinding in Mazes in Unity2D
  2. Implement Mazes in Unity2D
  3. Reusable Finite State Machine using C++
  4. Flocking and Boids Simulation in Unity2D
  5. Runtime Depth Sorting of Sprites in a Layer
  6. Implement Constant Size Sprite in Unity2D
  7. Implement Camera Pan and Zoom Controls in Unity2D
  8. Implement Drag and Drop Item in Unity
  9. Graph-Based Pathfinding Using C# in Unity
  10. 2D Grid-Based Pathfinding Using C# and Unity
  11. 8-Puzzle Problem Using A* in C# and Unity
  12. Create a Jigsaw Puzzle Game in Unity
  13. Implement a Generic Pathfinder in Unity using C#
  14. Create a Jigsaw Puzzle Game in Unity
  15. Generic Finite State Machine Using C#
  16. Implement Bezier Curve using C# in Unity
  17. Create a Jigsaw Tile from an Existing Image
  18. Create a Jigsaw Board from an Existing Image
  19. Solving 8 puzzle problem using A* star search
  20. A Configurable Third-Person Camera in Unity
  21. Player Controls With Finite State Machine Using C# in Unity
  22. Finite State Machine Using C# Delegates in Unity
  23. Enemy Behaviour With Finite State Machine Using C# Delegates in Unity
  24. Augmented Reality – Fire Effect using Vuforia and Unity
  25. Implementing a Finite State Machine Using C# in Unity
  26. Solving 8 puzzle problem using A* star search in C++
  27. What Are C# Delegates And How To Use Them
  28. How to Generate Mazes Using Depth-First Algorithm

Leave a Reply

Your email address will not be published. Required fields are marked *