Reputation: 53
I have this design:
public interface IFactory<T> {
T Create();
T CreateWithSensibleDefaults();
}
public class AppleFactory : IFactory<Apple> { ... }
public class BananaFactory : IFactory<Banana> { ... }
// ...
The fictitious Apple
and Banana
here do not necessarily share any common types (other than object
, of course).
I don't want clients to have to depend on specific factories, so instead, you can just ask a FactoryManager
for a new type. It has a FactoryForType
method:
IFactory<T> FactoryForType<T>();
Now you can invoke the appropriate interface methods with something like FactoryForType<Apple>().Create()
. So far, so good.
But there's a problem at the implementation level: how do I store this mapping from types to IFactory<T>
s? The naive answer is an IDictionary<Type, IFactory<T>>
, but that doesn't work since there's no type covariance on the T
(I'm using C# 3.5). Am I just stuck with an IDictionary<Type, object>
and doing the casting manually?
Upvotes: 4
Views: 250
Reputation: 754585
Unfortunately yes you are stuck with the manual casting. However this casting can be an implementation detail and not seen by the consumer. For example
public class FactoryMap {
private Dictionary<Type,object> _map = new Dictionary<Type,object>();
public void Add<T>(IFactory<T> factory) {
_map[typeof(T)] = factory;
}
public IFactory<T> Get<T>() {
return (IFactory<T>)_map[typeof(T)];
}
}
Upvotes: 5