First of all, it's not clear why you're creating classes derived from your generic class, rather than using the generic class directly. Nor is it clear why you need a factory rather than just instantiating whatever classes you need directly. These patterns are important and useful, often the only way to solve certain problems, but they're not requirements. You should have good reasons to implement them.
I'll assume, though, you do indeed have good reasons that you've elided for the sake of brevity.
The point of using the factory pattern is to have some piece of code instantiate the correct class without that code knowing the correct class. Note that in your example this separation is missing: whoever is calling MyClassFactory.CreateMyClass<T> ()
must know the correct class, since that code has to pass the type as a generic parameter, which determines the correct class. If I know enough to call CreateMyClass<int> ()
, then I know enough to call new MyDerivedIntClass ()
.
There are two primary ways of implementing the factory pattern: static functions and factory classes.
With both methods, you'll need an abstract base class or interface "underneath" the generics:
public interface IMyInterface
{
string Foo ();
}
public abstract class MyGenericBaseClass<T> : IMyInterface
{
// ...
abstract /* or virtual */ string Foo ();
}
Using the static function, you'll need a delegate type defined somewhere (class scope omitted):
// note: I'm not sure this is the correct syntax, but I think I'm in the ballpark
delegate IMyInterface MyInterfaceFactory ();
and the classes can implement them to return the correct type.
public sealed class MyDerivedIntClass : MyGenericBaseClass<int>
{
// ...
static IMyInterface CreateObject () { return new MyDerivedIntClass (); }
}
public sealed class MyDerivedStringClass : MyGenericBaseClass<string>
{
// ...
static IMyInterface CreateObject () { return new MyDerivedStringClass (); }
}
You pass the static function to the function that instantiates the object:
// ... somewhere else in the code ...
// create a IMyInterface object using a factory method and do something with it
void Bar (MyInterfaceFactory factory)
{
IMyInterface mySomething = factory ();
string foo = mySomething.Foo ();
}
// ... somewhere else in the code ...
void FooBarAnInt ()
{
Bar (MyDerivedIntClass.CreateObject);
}
The second method is to use factory classes:
public interface IMyInterfaceFactory
{
IMyInterface CreateObject ();
}
public class MyDerivedIntFactory : IMyInterfaceFactory
{
public IMyInterface CreateObject () { return new MyDerivedIntClass (); }
}
public class MyDerivedStringFactory : IMyInterfaceFactory
{
public IMyInterface CreateObject () { return new MyDerivedStringClass (); }
}
// ... somewhere else ...
// create a IMyInterface object using a factory class and do something with it
void Bar (IMyInterfaceFactory factory)
{
IMyInterface mySomething = factory.CreateObject ();
string foo = mySomething.Foo ();
}
// ... somewhere else in the code ...
void FooBarAnInt ()
{
Bar (new MyDerivedIntFactory ());
}
Note that you can (and probably should) also make the factory classes singletons, but that's a different problem. Also, you can use an abstract base class instead of an interface; you'll need to add abstract
(or virtual
) and override
as required.
Fundamentally, someone, somewhere, somehow has to know the correct type of object to instantiate. The point of factory objects is not to abstract that knowledge away completely, but to separate the knowledge of what type of object to create from the code that actually creates the object. If you don't need that separation, the factory pattern is not particularly useful.