Click here to Skip to main content
15,883,901 members
Articles / Programming Languages / C#
Tip/Trick

Implementing C# Factory Pattern with Dynamic Class Loading

Rate me:
Please Sign up or sign in to vote.
1.67/5 (3 votes)
6 Dec 2017CPOL1 min read 26.4K   3   4
Guide on creating a C# Factory Pattern with Dynamic Class Loading

Introduction

The Factory pattern is frequently used to de-couple service implementations. In C#, you can easily create a factory for dynamic class loading. I used this article as a basis, however, this factory is for Service, rather than for domain layer.

Background

In this example, unlike the example above, we will create a service factory. Service layer is the most frequent layer which will need tweaking, seeing as how database layers are often swapped. For example, you coded the software using stored procedures for insertion, but later need to switch to Entity Framework. This allows you to easily do so, by recoding implementation, and then "swapping" the said implementation.

Using the Code

First, you will need your Factory Class. This is the class which will be instantiated in order to lookup the key in the configuration file, and subsequently, it will be used to return the correct service implementation for that application version. In this application, we will be using service implementations.

C#
using System;
using System.Linq;
using System.Configuration;

namespace MyProject.Factory
{
    public class Factory
    {
        public static Factory GetInstance()
        {
            return new Factory();
        }

        public IService GetImpl(string svcName)
        {
            string implName = GetImplName(svcName);
            Console.WriteLine(implName);
            Type type = Type.GetType(implName, true);
            IService newInstance = (IService)Activator.CreateInstance(type);
            return newInstance; 
        }

        public string GetImplName(string typeName)
        {
            string implName=ConfigurationManager.AppSettings[typeName];
            return implName;
        }
    }
}

You will need a parent Service Interface. This interface will be inherited by all child service interfaces. The child service interfaces will then be implemented by concrete classes.

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyProject.Service
{
    public interface IService //top level for use by factory pattern
    {
 
    }
}

Now, we create the Service Interfaces. Decide on what the service will do, and inherit from the parent Service Interface.

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyProject.Service
{
    public interface IMyService: IService
    {
		public bool MyMethod1();
		public bool MyMethod2(string input);

    }
} 

Let's implement the service interface. For now, we will just code it "TDD" style. YOu will need to provide proper implementations.

C#
using System;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Security.Permissions;
using Microsoft.Win32.SafeHandles;
using System.Runtime.ConstrainedExecution;
using System.Security;
using FileCopier.Service;
using System.Configuration;

namespace FileCopier.Service
{
    public class ImpersonationSvcImpl : IImpersonationSvc
    {
		public bool MyMethod1(){
			throw new NotImplementedException();			
		}
		
		public bool MyMethod2(string input);
		{
			throw new NotImplementedException();
		}
	}
} 

Next, you will need an app.Config file which lists your services and implementation classes.

XML
 <?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
 <appSettings>
  <!-- service implementations-->
  <add key="IMyService" value="MyProject.Service.IMyServiceImpl"/>
 </appSettings>
</configuration>

Build your test classes:

C#
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using FileCopier.Service.Factory;
using FileCopier.Service;
using System.Configuration;

namespace MyFactoryDemoTest
{
    [TestClass]
    public class FactoryTest
    {
        [TestMethod]
        public void TesFactory1()
        {
            string svcName = "IMyService";
            Factory f = Factory.GetInstance();
            string implName = f.GetImplName(svcName);
            Console.WriteLine(implName);
            Assert.IsNotNull(implName);
        }

        [TestMethod]
        public void TesFactory2()
        {
            string svcName = "IMyService";
            Factory f = Factory.GetInstance();
            IGetSettingsSvc setSvc = (IGetSettingsSvc)f.GetImpl(svcName);
            Assert.IsNotNull(setSvc);
        }

        [TestMethod]
        public void TestFactoryIMyServiceg()
        {
            string svcName = "IMyService";
            Factory f = Factory.GetInstance();
            IGetSettingsSvc setSvc = (IGetSettingsSvc)f.GetImpl(svcName);             
        }

        public string GetImplName(string typeName)
        {
            string implName = ConfigurationManager.AppSettings[typeName];
            return implName;
        }     
    }
} 

License

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


Written By
United States United States
This member doesn't quite have enough reputation to be able to display their biography and homepage.

Comments and Discussions

 
QuestionHoo boy Pin
Pete O'Hanlon7-Dec-17 4:42
mvePete O'Hanlon7-Dec-17 4:42 
AnswerRe: Hoo boy Pin
Foothill7-Dec-17 8:28
professionalFoothill7-Dec-17 8:28 
GeneralRe: Hoo boy Pin
Pete O'Hanlon7-Dec-17 10:00
mvePete O'Hanlon7-Dec-17 10:00 
GeneralRe: Hoo boy Pin
BI Road Warrior11-Dec-17 5:49
BI Road Warrior11-Dec-17 5:49 

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.