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.
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.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyProject.Service
{
public interface IService
{
}
}
Now, we create the Service
Interfaces. Decide on what the service
will do, and inherit from the parent Service
Interface.
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.
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.
="1.0"="utf-8"
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<appSettings>
<add key="IMyService" value="MyProject.Service.IMyServiceImpl"/>
</appSettings>
</configuration>
Build your test classes:
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;
}
}
}
This member doesn't quite have enough reputation to be able to display their biography and homepage.