Tuesday, 5 February 2019

Factory Design Pattern in C#

Factory Design Pattern

In Factory pattern, we create the object without exposing the creation logic. In this pattern, an interface is used for creating an object, but let subclass decide which class to instantiate. The creation of object is done when it is required. The Factory method allows a class later instantiation to sub classes.

In short, factory method design pattern abstract the process of object creation and allows the object to be created at run-time when it is required.

Example :- Employee

A) Class Library :- Test.Employee


1) EmployeeFactory

using System;
using System.Configuration;

namespace Test.Employee
{
    public class EmployeeFactory
    {
        private static Type _empType;

        private static string GetTypeName(string factoryName)
        {
            var nameSpace = ConfigurationManager.AppSettings["EmployeeFactory"];
            return String.Format("{0}.{1}, {0}", nameSpace, factoryName);
        }

        public static IEmployeeManager GetManager()
        {
            if (_empType == null)
            {
                var empTypeName = GetTypeName("EmployeeManager");
                if (!string.IsNullOrEmpty(empTypeName))
                    _empType = Type.GetType(empTypeName);
                else
                    throw new NullReferenceException("EmployeeManagerType");
                if (_empType == null)
                    throw new ArgumentException(string.Format("Type {0} could not be found", empTypeName));
            }
            return (IEmployeeManager)Activator.CreateInstance(_empType);
        }
    }
}

2) IEmployee (Interface)

namespace Test.Employee
{
    public interface IEmployee
    {
        string Name { get; set; }

        int GetSalary();
    }
}

3) IEmployeeManager (Interface)

using System;

namespace Test.Employee
{
    public interface IEmployeeManager : IDisposable
    {
        string Data { get; set; }

        T GetProvider<T>() where T : class;
    }
}

B) Class Library :- Test.Employee.Parmanent

1) Employee (Class)

namespace Test.Employee.Parmanent
{
    public class Employee : IEmployee
    {
        public string Name { get; set; } = "Permanent";
        public int InHandSalary { get; set; }
        public int PF { get; set; }

        public int GetSalary()
        {
            return InHandSalary + PF;
        }
    }
}

2) EmployeeManager 

using System;

namespace Test.Employee.Parmanent
{
    public class EmployeeManager : IEmployeeManager
    {
        private static string _typeMask = typeof(EmployeeManager).FullName.Replace("EmployeeManager", @"{0}");

        private object _NewInstance = null;

        public string Data { get; set; }

        public T GetProvider<T>() where T : class
        {
            var typeName = string.Format(_typeMask, typeof(T).Name.Substring(1));
            var type = Type.GetType(typeName);
            if (type != null)
            {
                _NewInstance = Activator.CreateInstance(type);
                return _NewInstance as T;
            }
            else
                throw new NotImplementedException(typeName);
        }

        public void Dispose()
        {
            if (_NewInstance is IDisposable)
            {
                ((IDisposable)_NewInstance).Dispose();
            }
            _NewInstance = null;
        }
    }
}

C) Class Library :- Test.Employee.Temporary

1) Employee  (Class)

namespace Test.Employee.Temporary
{
    public class Employee : IEmployee
    {
        public string Name { get; set; } = "Temporary";

        public int InHandSalary { get; set; }

        public int PF { get; set; }

        public int GetSalary()
        {
            return InHandSalary + PF;
        }
    }
}

2)EmployeeManager  (Class) 

using System;

namespace Test.Employee.Temporary
{
    public class EmployeeManager : IEmployeeManager
    {
        private static string _typeMask = typeof(EmployeeManager).FullName.Replace("EmployeeManager", @"{0}");

        private object _NewInstance = null;

        public string Data { get; set; }

        public T GetProvider<T>() where T : class
        {
            var typeName = string.Format(_typeMask, typeof(T).Name.Substring(1));
            var type = Type.GetType(typeName);
            if (type != null)
            {
                _NewInstance = Activator.CreateInstance(type);
                return _NewInstance as T;
            }
            else
                throw new NotImplementedException(typeName);
        }

        public void Dispose()
        {
            if (_NewInstance is IDisposable)
            {
                ((IDisposable)_NewInstance).Dispose();
            }
            _NewInstance = null;
        }
    }
}

4) Console Application :- TestFactoryPattern

1) Program (Class)

using System;
using Test.Employee;

namespace TestFactoryPattern
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            try
            {
                using (var empManager = EmployeeFactory.GetManager())
                {
                    var employee = empManager.GetProvider<IEmployee>();
                    Console.WriteLine(employee.Name);
                    Console.ReadLine();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.ReadLine();
            }
        }
    }
}

2) App.Config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
  </startup>
  <appSettings>
    <add key="EmployeeFactory" value="Test.Employee.Parmanent" />
    <!--<add key="EmployeeFactory" value="Test.Employee.Temporary" />-->
  </appSettings>
</configuration>

Note :- 
        a) Pass the reference Test.Employee To All Project 
        b) Test.Employee.Permanent & Test.Employee.Temporary in Console App
        c) Configure any one at Run time by using config file

Result :- if you set "Test.Employee.Parmanent" in config then result will shown of Permanent 



2 comments:

  1. The Factory Design Pattern is a smart choice for managing object creation. Its clean separation of concerns enhances the maintainability of codebases. Future Digital India A valuable pattern that empowers developers to write efficient and modular code.

    ReplyDelete

Factorial of a Number

Recently Viewed