Click here to Skip to main content
Click here to Skip to main content

Another class factory

, 3 May 2003
Rate this:
Please Sign up or sign in to vote.
Class Factory based on C# events & delegate
<!-- Article image -->

Sample Image - AnotherClassFactory.jpg

Introduction

I came across the need for a class factory that can create instances of a wide range of objects, which will be flexible enough to support classes that are unknown to the factory. I started skimming for such a solution but surprisingly none was found (all though I found a lot of "Class Factory articles"). During my search I found an article wrote by Chris Sells that explains events & delegates .NET Delegates: A C# Bedtime Story.

This article gave me the idea to use the events mechanism to broadcast a request for a new instance, any listener that feels that he is the right creator can create a instance and return it.

Using the code

In order to use the ClassFactory add a reference to ClassFactory.dll  to your project. In the class that needs to be created with the Factory add a static method with the following signature:

/// Class A will be created with the ClassFactory 
/// so it has a static metod.
/// this method will be use as a event handler.
public class A
{
    public static void Creator(object sender, 
        Yoramo.ClassFactory.CreateObjectArgs e)
    {
        if (e._Key == "A" && e._CreatedObject == null)
            e._CreatedObject = new A() ;
    }
}

Create an instance of the factory (you can derive it and modify it to be a singleton if you like).

Yoramo.ClassFactory.ClassFactory aFactory = 
    new Yoramo.ClassFactory.ClassFactory() ;

Add the class's delegator method to the factory.

aFactory.CreateIt += new Yoramo.ClassFactory.CreateObjectEvent(
    A.Creator) ;
aFactory.CreateIt += new Yoramo.ClassFactory.CreateObjectEvent(
    B.Creator) ;
aFactory.CreateIt += new Yoramo.ClassFactory.CreateObjectEvent(
    C.Creator) ;

Now you can call the create method with a string as a parameter and one of your classes can respond with a new instance.

object aObj = aFactory.Create("A") ; // create an object with Key="A"

Drawbacks

I could not find a way to stop the broadcasting in case that any creator has created the needed instance, all the other listeners that are in the list will continue receiving the event even though the request has been fulfilled. Because of that they need politely to return immediately. This behavior enables a creator to overwrite the product of a previous creator (which is not a desired behaviour).

With the help of 'pbackhuvud' I have modified the code to overcome the broadcasting problem. Here is the final result

public object Create(string iKey)
{
   CreateObjectArgs aArgs = new CreateObjectArgs(iKey) ;
   if (CreateIt != null)
   {
    foreach (CreateObjectEvent Handler in 
            CreateIt.GetInvocationList())
    {
       try 
       {
        if (aArgs._CreatedObject == null)
           Handler(this,aArgs) ; // try to create the object.
        else
           break ;  // the instance has been created. 
                    // stop the serch for a creator.
       } 
       catch (Exception ex)
           {
        System.Diagnostics.Debug.Assert(false,
                   "A Creator as raised an exception !!!") ;
       }
    }
   }
   return aArgs._CreatedObject ;
}

The Code

using System;

namespace Yoramo.ClassFactory
{
    /// <SUMMARY>
    /// delegator for ClassFactory create.
    /// </SUMMARY>
    public delegate void CreateObjectEvent(object iSender, 
           CreateObjectArgs e) ;

    /// <SUMMARY>
    /// Summary description for ClassFactory.
    /// </SUMMARY>
    public class ClassFactory
    {
        /// <SUMMARY>
        /// Declare the Event
        /// </SUMMARY>
        public event CreateObjectEvent CreateIt ; 

        /// <SUMMARY>
        /// Try to create a instance of a class 
        /// that recognize the key "iKey"
        /// </SUMMARY>
        /// <PARAM name="iKey"> string value that indicates the needed class</PARAM>
        /// <RETURNS>object - The istance created or 
        /// null if no instance was created</RETURNS>
        public object Create(string iKey)
        {
            CreateObjectArgs aArgs = new CreateObjectArgs(iKey) ;
            if (CreateIt != null)
               CreateIt(this,aArgs) ;

            return aArgs._CreatedObject ;
        }
    }

    #region EventArgs derive class
    /// <SUMMARY>
    /// Summary description for CreateObjectArgs.
    /// A derivation of EventArgs.
    /// Additional information:
    ///        - _Key - The Key that specifie the nequested class
    ///        - _CreatedObject - The object instance that 
    ///                  was created (return value)
    ///            
    ///    The factory class will create a instance of 
    ///    this EventArgs derivation and 
    ///    initialize the _Key member. This inctance will 
    ///    be passed to the event and
    ///    the result will be in the  _CreatedObject member.
    /// </SUMMARY>
    public class CreateObjectArgs : EventArgs
    {
        /// <SUMMARY>
        /// Constractor
        /// </SUMMARY>
        /// <PARAM name="iKey">string value, use it as a key</PARAM>
        public CreateObjectArgs (string iKey)
        {
            _Key = iKey ;
            _CreatedObject = null ;
        }
        /// <SUMMARY>
        /// Identification key for the instance class.
        /// </SUMMARY>
        public string _Key ;
        /// <SUMMARY>
        /// Return the new instance in this member
        /// </SUMMARY>
        public object _CreatedObject ;
    }
    #endregion
}

License

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

About the Author

Yoramo
Architect
Israel Israel
No Biography provided

Comments and Discussions

 
GeneralHmm Pinmemberpbackhuvud5-May-03 20:49 
GeneralRe: Hmm PinmemberYoramo7-May-03 5:58 
GeneralRe: Hmm Pinmemberpbackhuvud7-May-03 11:18 
GeneralRe: Hmm PinmemberYoramo8-May-03 9:03 

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

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

| Advertise | Privacy | Mobile
Web04 | 2.8.140721.1 | Last Updated 4 May 2003
Article Copyright 2003 by Yoramo
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid