I have a generic object factory FactoryBase<T> with a factory method:
public abstract class FactoryBase<T> where T : new()
{
public virtual T CreateInstance()
{
T thing = new T();
// Tweak 'thing' a bit...
return thing;
}
}
This works great for creating concrete factories for various types:
public class FruitFactory : FactoryBase<Fruit>
{
public override Fruit CreateInstance()
{
Fruit fruit = base.CreateInstance();
// Do some Fruit polishing stuff...
return fruit;
}
}
However, the pattern breaks down if I want to create a factory type derived from Fruit:
First attempt: (WORKS, but INCORRECT)
Here, AppleFactory directly inherits FactoryBase<Apple> — this is wrong because AppleFactory should rely upon FruitFactory to build a nice polished Fruit upon which to build our Apple:
// Should inherit FruitFactory, not FactoryBase
public class AppleFactory : FactoryBase<Apple>
{
public override Apple CreateInstance()
{
Apple apple = base.CreateInstance();
// FruitFactory is left out above, so...
// ...we have to do all the Fruit polishing stuff...
// ... and any apple stuff...
return apple;
}
}
Second attempt: (Complete fail)
Inheriting FruitFactory is clearly an error because it is non-generic and returns a Fruit not an Apple:
// COMPILE ERRORS
public class AppleFactory : FruitFactory
{
public override Apple CreateInstance() // ERROR: Override method must return Fruit
{
Apple apple = base.CreateInstance(); // ERROR: FruitFactory returns a Fruit
return apple;
}
}
The “Ugly” Solution?
By refactoring FruitFactory into a genericFruitFactory<T> I can create a properly derived AppleFactory:
public abstract class FruitFactory<T> where T : Fruit, new()
{
public override T CreateInstance()
{
T fruit = (T)base.CreateInstance();
// Do some Fruit polishing stuff...
return fruit;
}
}
// AppleFactory that property calls FruitFactory<Apple>
public class AppleFactory : FruitFactory<Apple>
{
public override Apple CreateInstance()
{
Apple apple = base.CreateInstance();
// ... ONLY apple stuff needed!!!
return apple;
}
}
I purposely make FruitFactory<T> abstract because it seems ugly and redundant for client code to call upon a a FruitFactory<Fruit>. Thus, I provide a non-generic FruitFactory which needs no body to be fully functional:
// Concrete FruitFactory
public class FruitFactory : FruitFactory<Fruit> { }
Complaints:
Each time I need a factory for a more-derived type I have to convert the corresponding base type’s factory to an abstract generic.
In other words, if I have a FooFactory I have to convert it to a FooFactory<T> in order to create DerivedFooFactory : FooFactory<DerivedFoo>
Simultaneously, I must make a new concrete FooFactory : FooFactory<Foo>.
Or… I could the generic factories directly:
var fruitFactory = new FruitFactory<Fruit>(); // Double-Fruity! sigh...
Is there a cleaner way to create an AppleFactory that first gets an Apple out of a FruitFactory without needing generic classes for each ‘middle-man’ type in the inheritance chain?
Note: I really don’t want to use reflection or complex schemes.
I’m still having trouble following your question, but I think it would be solved by making
FruitFactory<T>non-abstract:Then you can derive from that and override
CreateInstancewhen you writeAppleFactory.