DeepT
February 14th, 2008, 12:14 PM
I have been using relfection to help me make object factories for a while. Currently I am doing something like this:
Base Class:
public abstract class AWPESD_BASE
{
public class AWPESD_Builder
{
public delegate AWPESD_BASE Builder();
public Builder Build;
public AWPESD_Builder(Builder Bld)
{
Build = Bld;
}
}
static AWPESD_BASE()
{
Assembly Asm = Assembly.GetExecutingAssembly();
Type[] Types = Asm.GetTypes();
object[] Prams = new object[0];
foreach (Type T in Types)
{
if (true == T.IsSubclassOf(typeof(AWPESD_BASE)))
{
MethodInfo Method = T.GetMethod("RegisterWith_AWPESD_BASE");
if (null != Method)
{
Method.Invoke(null, Prams);
}
}
}
}
private static Dictionary<string, AWPESD_Builder> SubBuilders = new Dictionary<string, AWPESD_Builder>();
protected static void RegisterSubClass(string TypeName, AWPESD_Builder Bld)
{
SubBuilders.Add(TypeName, Bld);
}
public static AWPESD_BASE Create(string TypeName)
{
AWPESD_Builder Bld;
AWPESD_BASE Data = null;
if (true == SubBuilders.TryGetValue(TypeName, out Bld))
{
Data = Bld.Build();
}
return Data;
}
SubClass:
public class AWPESD_NumRange : AWPESD_BASE
{
public AWPESD_NumRange()
{
}
private static string XMLTag = "AWPESD_NumRange";
public static void RegisterWith_AWPESD_BASE()
{
RegisterSubClass(XMLTag, new AWPESD_Builder(Build));
}
public static AWPESD_BASE Build()
{
return new AWPESD_NumRange();
}
This works well and good, but I am thinking there is likely an even cleaner way to do this.
One thing this lacks is the benefit of "static abstract" which only makes sense in the context of reflection. The "static" part is needed because I do not know how to create instances of a class without directly using it's type or a delegate. In the above example, the builder method is static so it can exist without an instance of the class, and thus the register method can create a delegate which is then added to the sub-type collection.
The abstract part, which does not exist in this example, would ensure that all sub-classes MUST implement the Build() method. The build method, can't be anything but static since the actual instance doesn't exist, and as we all know, if something is static, it can't be abstract.
If I could figure out how to create an instance of an object via "something" I got through reflection, then I could drop the Builder part.
Ideally Factory 2.0 would NOT require the sub-classes to do anything special (like have static methods) and would be able to create a list of sub-classes by the sub-class name. I could then just pass in the sub-class name and have it somehow create an instance of the sub-class.
Any ideas on how to do this? My current method works fine, it is just a bit clunky.
Base Class:
public abstract class AWPESD_BASE
{
public class AWPESD_Builder
{
public delegate AWPESD_BASE Builder();
public Builder Build;
public AWPESD_Builder(Builder Bld)
{
Build = Bld;
}
}
static AWPESD_BASE()
{
Assembly Asm = Assembly.GetExecutingAssembly();
Type[] Types = Asm.GetTypes();
object[] Prams = new object[0];
foreach (Type T in Types)
{
if (true == T.IsSubclassOf(typeof(AWPESD_BASE)))
{
MethodInfo Method = T.GetMethod("RegisterWith_AWPESD_BASE");
if (null != Method)
{
Method.Invoke(null, Prams);
}
}
}
}
private static Dictionary<string, AWPESD_Builder> SubBuilders = new Dictionary<string, AWPESD_Builder>();
protected static void RegisterSubClass(string TypeName, AWPESD_Builder Bld)
{
SubBuilders.Add(TypeName, Bld);
}
public static AWPESD_BASE Create(string TypeName)
{
AWPESD_Builder Bld;
AWPESD_BASE Data = null;
if (true == SubBuilders.TryGetValue(TypeName, out Bld))
{
Data = Bld.Build();
}
return Data;
}
SubClass:
public class AWPESD_NumRange : AWPESD_BASE
{
public AWPESD_NumRange()
{
}
private static string XMLTag = "AWPESD_NumRange";
public static void RegisterWith_AWPESD_BASE()
{
RegisterSubClass(XMLTag, new AWPESD_Builder(Build));
}
public static AWPESD_BASE Build()
{
return new AWPESD_NumRange();
}
This works well and good, but I am thinking there is likely an even cleaner way to do this.
One thing this lacks is the benefit of "static abstract" which only makes sense in the context of reflection. The "static" part is needed because I do not know how to create instances of a class without directly using it's type or a delegate. In the above example, the builder method is static so it can exist without an instance of the class, and thus the register method can create a delegate which is then added to the sub-type collection.
The abstract part, which does not exist in this example, would ensure that all sub-classes MUST implement the Build() method. The build method, can't be anything but static since the actual instance doesn't exist, and as we all know, if something is static, it can't be abstract.
If I could figure out how to create an instance of an object via "something" I got through reflection, then I could drop the Builder part.
Ideally Factory 2.0 would NOT require the sub-classes to do anything special (like have static methods) and would be able to create a list of sub-classes by the sub-class name. I could then just pass in the sub-class name and have it somehow create an instance of the sub-class.
Any ideas on how to do this? My current method works fine, it is just a bit clunky.