Ciao,
Sto lavorando a un'applicazione un pò grande e i progettisti hanno deciso, per ottimizzare alcune cose, di creare una cache temporanea implementata con un Dictionary
La soluzione migliore consiste nell'usare l'
oggetto MemoryCache, che è stato progettato appositamente allo scopo di tenere in cache degli oggetti.
Un Dictionary non è una buona scelta. La proprietà Providers è static, giusto? Se è così è un problema perché varie richieste contemporanee possono leggere/scrivere contemporaneamente il dizionario e avrai degli effetti indesiderati perché la classe Dictionary NON è thread-safe.
Inoltre, penso che l'errore di chiave duplicata lo hai perché tra la chiamata a ContainsKey e la chiamata a Add arriva una seconda richiesta contemporanea che aggiunge la chiave al dizionario.
La soluzione ad entrambi i problemi è la classe ConcurrentDictionary, che è
thread-safe e ti permette, in maniera atomica, di ottenere un valore di una chiave dal dizionario o di aggiungerla se non dovesse esistere.
Quindi, dichiari il dizionario:
private static ConcurrentDictionary<string, object> providers = new ConcurrentDictionary<string, object>();
public static ConcurrentDictionary<string, object> Providers { get { return providers; } }
E poi ottieni il valore o lo aggiungi se non esiste, usando il metodo GeOrAdd. Nota come il secondo parametro sia una Func, che verrà invocata dal dizionario solo se c'è l'effettivo bisogno di creare il valore (che si presume sia costoso da costruire, altrimenti non useresti cache).
var valore = this.Providers.GetOrAdd(entityTypeName, chiave => OttieniIstanzaDiProvider());
Il parametro che a te interessa è InstanceContextMode,
Questo regola la creazione delle istanze del servizio e non aiuta a risolvere il problema della cache.
ciao,
Moreno