Come posso fare questo semplice C # generici lavoro in fabbrica?
Domanda
ho questo disegno:
public interface IFactory<T> {
T Create();
T CreateWithSensibleDefaults();
}
public class AppleFactory : IFactory<Apple> { ... }
public class BananaFactory : IFactory<Banana> { ... }
// ...
Il Apple
fittizio e Banana
qui non necessariamente condividono alcun tipi comuni (diversi object
, ovviamente).
Non voglio clienti di avere a dipendere da specifici fabbriche, così invece, si può solo chiedere un FactoryManager
per un nuovo tipo. Ha un metodo di FactoryForType
:
IFactory<T> FactoryForType<T>();
Ora è possibile richiamare i metodi di interfaccia appropriati con qualcosa di simile FactoryForType<Apple>().Create()
. Fin qui, tutto bene.
Ma c'è un problema a livello di implementazione: come faccio a conservare questa mappatura da tipi di IFactory<T>
s? La risposta è un ingenuo IDictionary<Type, IFactory<T>>
, ma questo non funziona perché non c'è nessun tipo di covarianza sul T
(sto usando C # 3.5). Am Ho appena bloccato con un IDictionary<Type, object>
e facendo il casting manualmente?
Soluzione
Purtroppo sì si è bloccato con la fusione manuale. Tuttavia questo casting può essere un dettaglio di implementazione e non visto dal consumatore. Ad esempio
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)];
}
}