Reflective factory for .NET (C#)

What is this about? It is about creating instances of classes in a simple AND extensible way.

Applications should always be built in a modular way, to illustrate this let us look at a simple client-server application.
You may give the user some options for the transport mechanism:

  • An unencrypted TCP transport
  • And an encrypted SSL transport, to use over untrusted networks.

A first approach is to simply use 'tcp' and 'ssl' in the configuration file of the client/server to indicate which transport mechanism to use. This definitly is a user friendly way because they are short, easy to remember and the user knows the terms 'tcp' and 'ssl', but is not very extensible. Assume you want to add another transport mechanism or want to include third party transport mechanisms, you always need to deliver a modified application executable which includes the new identifier.

When it comes to .NET another approach is to use fully qualified class names, this would look something like 'My.very.complicated.namespace.noone.can.remember.tcp, my.assembly'. This approach is not very user friendly because noone can remember the class names, BUT it is very extensible. You even can extend your application with external or third-party libraries without delivering modified application executables.

But there is another approach which combines the best of both worlds. The final result is that you can specify short identifiers for classes (like 'tcp' or 'ssl'). These identifiers get attached to the classes by specifying a class-level-attribute, so no enumeration of all possible 'short' identifiers exist, thus, they can be extended easily even with external applications. But you/or third party extensions can also use fully qualified names to create instances.

Samples

First let's create some classes with base class to be instantiated. The ClassIdentifier attributes already get attached to two of the three classes to be instantiated

public abstract class CIBase{
 private string _name;
			
 public CIBase(string name){
  _name = name;
 }
			
 public override string ToString (){
  return _name;
 }
}
		
[ClassIdentifier("c1")]
public class CIClass1 : CIBase{
  public CIClass1(string name) : base(name){
  }
}
		
[ClassIdentifier("c2")]
public class CIClass2 : CIBase{
  public CIClass2(string name) : base(name){
  }
}
		
public class CIClass3 : CIBase{
  public CIClass3(string name) : base(name){
  }
}

To generate some instances now we invoke the CreateFromClassIdentifierOrType method. The first two calls use the short class identifiers, the third one uses the full name. After the identifier the parameters for the constructor need to be specified, the factory automatically looks for the correct ctor if more than one exists.

CIBase o1 = GenericClassIdentifierFactory.CreateFromClassIdentifierOrType<CIBase>("c1", "class number 1");
CIBase o2 = GenericClassIdentifierFactory.CreateFromClassIdentifierOrType<CIBase>("c2", "class number 2");
CIBase o3 = GenericClassIdentifierFactory.CreateFromClassIdentifierOrType<CIBase>("Deveck.Utils.Samples.Program+CIClass3, Samples", "class number 3");

Source code

Check out the code at git clone git://github.com/deveck/Deveck.Utils.git Run the samples to see how it works, the factory is located at Deveck.Utils/Factory