Click here to Skip to main content
14,027,514 members
Click here to Skip to main content
Add your own
alternative version

Stats

22.5K views
271 downloads
31 bookmarked
Posted 30 Jan 2016
Licenced CPOL

Learning Factory Pattern using C#

, 21 Feb 2016
Rate this:
Please Sign up or sign in to vote.
Explaining Factory Pattern in C# using a Simple LoggerFactory.

Introduction

Factory pattern is very common in programming. If you check .NET framework or any other frameworks Factory Pattern is widely used which shows its popularity. Factory Pattern belongs to Creational Patterns, and it deals with object creation. In this article we shall try to learn Factory Pattern using a simple C# console application. 

Background

When we write codes we used to come across situations like creating objects based on some if conditions or switch case.  If this object creation is not based on a proven design pattern then we are really making the object creation complex and future enhancements very tough. At this time we should consider Factory Pattern to abstract the complexity of the object creation logic, and enabling future additions hassle free.

Let's take a very simple example of logging functionality in a project, If we had the implementation as below, then for adding a new Logging option requires considerable code changes at client code base which is not a good practice.   

public void Log(string message, string type)
{
    switch (type)
    {
        case "Database":
            DatabaseLogger databaseLogger =  new DatabaseLogger();
            databaseLogger.Log(message);
            break;
        case "EventViewer":
        default:
            EventViewerLogger eventviewerLogger =  new EventViewerLogger();
            eventviewerLogger.Log(message);
            break;
    }
}

Factory Pattern is nothing but hiding object creation logic from the client so that the end client doesn't have to worry about object creational logic, rather the client can refer the factory pattern created object using a common interface.  

Using the code

For better understanding we can create a simple Logger Factory which will help the client to log messages to different options based on their choice.  

Factory  Pattern Example in C#

To start with, we need to create an Interface or abstract class as the base class for all classes which we are going to create instance in factory. Here I have used an Interface ILogger with a method Log message.

 interface ILogger
{
    void Log(string Message);
}

Now we are going to implement this ILogger in all classes which we wanted to return from Logger Factory. Here ideally Log method should have the real method to log the message to a file but for demonstrating purpose I'm just adding a console message.

class FileLogger : ILogger
{
    public void Log(string Message)
    {
        Console.WriteLine("{0} - Logged in File.", Message);
    }
}

the same way implementing ILogger to DatabaseLogger, also Log method definition added.

class DatabaseLogger : ILogger
{
    public void Log(string Message)
    {
        Console.WriteLine("{0} - Logged in Database.", Message);
    }
}

EventViewerLogger also implemented from ILogger and Log method definition added based on the type. We can add new logger classes same as these logger classes.

class EventViewerLogger : ILogger
{
    public void Log(string Message)
    {
        Console.WriteLine("{0} - Logged in EventViewer.", Message);
    }
}

Create  an enum to easily identify the LoggerType, In case if we have a new LoggerType then we can add it here.

enum LoggerType
{
    File,
    Database,
    EventViewer
}

FInally we have reached to the LoggerFactory,now this factory will take care of the object creation based on the enum values, and will return the created instance back to client code which will be a type of ILogger.  

class LoggerFactory
{
    public static ILogger Get(LoggerType type)
    {
        switch (type)
        {
            case LoggerType.Database:
                return new DatabaseLogger();
            case LoggerType.EventViewer:
                return new EventViewerLogger();
            case LoggerType.File:
            default:
                return new FileLogger();
        }
    }
}

If you look at the above code you can see that the object creation logic is abstracted in the factory and the objects are created based the kind of object requested, as the return type is an Interface ILogger, the client code need not worry about new addition to the factory.

Have written a client code to make use of this factory as below,

static void Main(string[] args)
{
    ILogger logger1 = LoggerFactory.Get(LoggerType.Database);
    logger1.Log("Message from Main");

    ILogger logger2 = LoggerFactory.Get(LoggerType.File);
    logger2.Log("Message from Main");

    ILogger logger3 = LoggerFactory.Get(LoggerType.EventViewer);
    logger3.Log("Message from Main");

    Console.ReadKey();

    /*Output
    Message from Main - Logged in Database.
    Message from Main - Logged in File.
    Message from Main - Logged in EventViewer.
    */
}

In the above code the client code uses the enum to request a specific object and using that object the log method is called. Objects are created using ILogger and instantiated using factory. Have given the output below,

To explore this sample yourself you can download the attached code or create a console project named "FactoryPatternSample" and replace the content of Program.cs with below code block.

Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FactoryPatternSample
{
    class Program
    {
        interface ILogger
        {
            void Log(string Message);
        }

        enum LoggerType
        {
            File,
            Database,
            EventViewer
        }

        class FileLogger : ILogger
        {
            public void Log(string Message)
            {
                Console.WriteLine("{0} - Logged in File.", Message);
            }
        }

        class DatabaseLogger : ILogger
        {
            public void Log(string Message)
            {
                Console.WriteLine("{0} - Logged in Database.", Message);
            }
        }

        class EventViewerLogger : ILogger
        {
            public void Log(string Message)
            {
                Console.WriteLine("{0} - Logged in EventViewer.", Message);
            }
        }

        class LoggerFactory
        {
            public static ILogger Get(LoggerType type)
            {
                switch (type)
                {
                    case LoggerType.Database:
                        return new DatabaseLogger();
                    case LoggerType.EventViewer:
                        return new EventViewerLogger();
                    case LoggerType.File:
                    default:
                        return new FileLogger();
                }
            }
        }

        static void Main(string[] args)
        {
            ILogger logger1 = LoggerFactory.Get(LoggerType.Database);
            logger1.Log("Message from Main");

            ILogger logger2 = LoggerFactory.Get(LoggerType.File);
            logger2.Log("Message from Main");

            ILogger logger3 = LoggerFactory.Get(LoggerType.EventViewer);
            logger3.Log("Message from Main");

            Console.ReadKey();

            /*Output
            Message from Main - Logged in Database.
            Message from Main - Logged in File.
            Message from Main - Logged in EventViewer.
            */
        }
    }
}

Summary

In this article I have explained Factory Pattern with a simple C# application. I hope you have enjoyed this article and got some value addition to your knowledge. Please don't forget to mark your votes, suggestions and feedback to improve the quality of this and upcoming articles. 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Shemeer NS
Software Developer (Senior)
India India
Technology Specialist | CodeProject MVP | Visual Studio Gallery Contributor | Author | Geek | Netizen | Husband | ChessPlayer

Most of my articles are listed on top 5 of the respective 'Best articles of the month' and some of my articles are published on ASP.NET WebSite's Article of the Day section.

Check my contributions in Visual Studio Gallery and Code Project

Technical Blog: http://www.shemeerns.com
Facebook: http://facebook.com/shemeernsblog
Twitter : http://twitter.com/shemeerns
Google+ : http://google.com/+Shemeernsblog

You may also be interested in...

Pro
Pro

Comments and Discussions

 
QuestionThanks a good example! How to move FileLogger to another class? Pin
Member 125971697-Dec-17 3:52
memberMember 125971697-Dec-17 3:52 
GeneralMy vote of 5 Pin
viler8431-Oct-17 14:29
memberviler8431-Oct-17 14:29 
QuestionWith every new logger there are two changes Pin
Lechuss22-Feb-16 9:38
memberLechuss22-Feb-16 9:38 
AnswerRe: With every new logger there are two changes Pin
Shemeer NS23-Feb-16 2:42
memberShemeer NS23-Feb-16 2:42 
PraiseAppriciation Pin
Ayaz_Khan_Niazi22-Feb-16 2:07
memberAyaz_Khan_Niazi22-Feb-16 2:07 
PraiseEasy to understand Pin
User 756227311-Feb-16 20:21
memberUser 756227311-Feb-16 20:21 
GeneralMy vote of 5 Pin
jrobb2292-Feb-16 21:29
memberjrobb2292-Feb-16 21:29 
GeneralMy vote of 5 Pin
JayantaChatterjee31-Jan-16 22:09
professionalJayantaChatterjee31-Jan-16 22:09 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web01 | 2.8.190419.4 | Last Updated 21 Feb 2016
Article Copyright 2016 by Shemeer NS
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid