RSS Feed for This PostCurrent Article

.NET: Dynamic Object Factory

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);                      
                        
        }
 
    }
 
}


Trackback URL


RSS Feed for This PostPost a Comment