.NET: Dynamic Object Factory
By admin on Feb 2, 2009 in .NET, Programming
This is a dynamic way of creating different object factory for different types of gateway, which I used to connect to different kinds of servers.
This is the interface, IGatewayFactory
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MessageGateway.Core.Base
{
/// <summary>
/// Gateway factory interface
/// </summary>
/// <typeparam name=”T”>Derived gateway factory</typeparam>
internal interface IGatewayFactory
{
/// <summary>
/// Return the interface to the correct gateway
/// </summary>
/// <returns></returns>
IGateway Find();
}
}
The base class, BaseGatewayFactory
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MessageGateway.Core.Base
{
/// <summary>
/// Base class for all gateway factory
/// </summary>
/// <typeparam name=”T”>Derived gateway factory</typeparam>
internal abstract class BaseGatewayFactory<T>
{
}
}
Let’s say I need to connect to different mobile phones and I need to return the correct gateway for each type of phones. Here is the MobileGatewayFactory
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MessageGateway.Core.Base;
namespace MessageGateway.Core.Mobile
{
/// <summary>
/// Mobile gateway factory
/// </summary>
internal class MobileGatewayFactory : BaseGatewayFactory<MobileGateway>,
IGatewayFactory
{
#region ================== Private Variable ==========
/// <summary>
/// Mobile gateway configuration
/// </summary>
private MobileGatewayConfiguration config;
#endregion ===========================================
#region ================== Constructor ===============
/// <summary>
/// </summary>
/// <param name=”config”></param>
public MobileGatewayFactory(MobileGatewayConfiguration config)
{
this.config = config;
}
#endregion ============================================
#region ================== Public Methods =============
/// <summary>
/// </summary>
/// <returns></returns>
public IGateway Find()
{
MobileGateway mobileGateway = MobileGateway.NewInstance(config);
// Determine the mobile gateway model, and check if there is a
// customized gateway developed
// TODO
return mobileGateway;
}
#endregion ===========================================
}
}
Here is the code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using MessageGateway.Core.Base;
using MessageGateway.Core.Mobile;
namespace MessageGateway.Core
{
/// <summary>
/// This is the entry point to instantiate the desired gateway.
/// All access to the library must go through this library.
/// </summary>
/// <typeparam name=”G”>Gateway</typeparam>
/// <typeparam name=”C”>Gateway configuration</typeparam>
public class MessageServer<G,C>
{
#region ====================== Constructor ========================
/// <summary>
/// Private constructor
/// </summary>
private MessageServer()
{
}
#endregion ========================================================
#region ================= Public Properties ========================
#endregion ========================================================
#region ==================== Public Methods ========================
/// <summary>
/// Find and return the correct gateway instance based on the
/// configuration type
/// </summary>
/// <param name=”config”>Configuration object</param>
/// <returns>The required gateway interface</returns>
public G Find(C config)
{
Type paramType = config.GetType();
Assembly assembly = Assembly.GetAssembly(paramType);
Type[] types = assembly.GetTypes();
foreach (Type type in types)
{
if (type.GetInterface(typeof(IGatewayFactory).Name) != null)
{
ConstructorInfo constructorInfo = type.GetConstructor(new Type[] { paramType });
if (constructorInfo != null && constructorInfo.GetParameters()[0].ParameterType.Equals(paramType))
{
IGatewayFactory gatewayFactory = (IGatewayFactory)Activator.CreateInstance(type, new object[]{config});
return (G)gatewayFactory.Find();
}
}
}
return default(G);
}
#endregion ========================================================
#region ==================== Public Static Methods ================
/// <summary>
/// Create a new gateway instance
/// </summary>
/// <returns>A new gateway instance</returns>
public static MessageServer<G, C> NewInstance()
{
return new MessageServer<G, C>();
}
#endregion ========================================================
}
}
It uses Reflection and Activator.CreateInstance to create the correct factory based on the configuration type.
To test it,
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using MessageGateway.Core;
using MessageGateway.Core.Mobile;
using NUnit.Framework;
namespace MessageGateway.Core.Test
{
/// <summary>
/// NUnit test for MessageServer
/// </summary>
[TestFixture]
public class MessageServerTest
{
/// <summary>
/// Set up the test
/// </summary>
[SetUp]
protected void SetUp()
{
}
/// <summary>
/// Retrieve the gateway model
/// </summary>
[Test]
public void GetModel()
{
// Create the gateway for mobile
MessageServer<IMobileGateway, MobileGatewayConfiguration> messageServer =
MessageServer<IMobileGateway, MobileGatewayConfiguration>.NewInstance();
// Create the mobile gateway configuration
MobileGatewayConfiguration config = MobileGatewayConfiguration.NewInstance();
IMobileGateway mobileGateway = messageServer.Find(config);
Assert.IsNotNull(mobileGateway);
Assert.IsNotEmpty(mobileGateway.Model);
}
}
}
Post a Comment