Utilizzare il ChannelFactory per creare un'istanza della factory, quindi memorizzare nella cache quell'istanza. È quindi possibile creare i canali communicatino come necessario/desiderato dall'istanza memorizzata nella cache.
Avete bisogno di più fabbriche di canali (vale a dire, ci sono più servizi)? Nella mia esperienza, è qui che vedrai il più grande beneficio in termini di prestazioni. Creare un canale è un compito abbastanza economico; è tutto pronto all'inizio che richiede tempo.
Non memorizzo nella cache i singoli canali: li creo, li uso per un'operazione e li chiudo. Se li metti in cache, potrebbero scadere e il canale non funzionerà, quindi dovrai abortire e crearne uno nuovo.
Non sono sicuro del motivo per cui si desidera utilizzare singleton per implementare ChannelFactory, soprattutto se si intende crearlo e memorizzarlo nella cache, e c'è solo un endpoint.
Inserirò qualche codice di esempio più tardi quando avrò un po 'più di tempo.
UPDATE: esempi di codice
Ecco un esempio di come ho implementato questo per un progetto di lavoro. Ho usato ChannelFactory<T>
, in quanto l'applicazione che stavo sviluppando è un'app di n-tier con diversi servizi, e ne verranno aggiunti altri. L'obiettivo era quello di avere un modo semplice per creare un client una volta per tutta la vita dell'applicazione, e quindi creare canali di comunicazione secondo necessità. Le basi dell'idea non sono mie (l'ho preso da un articolo sul web), anche se ho modificato l'implementazione per i miei bisogni.
Nella mia applicazione ho una classe helper statica e all'interno di tale classe ho un dizionario e un metodo per creare canali di comunicazione dalla fabbrica di channelf.
Il dizionario è il seguente (oggetto è il valore in quanto conterrà diverse fabbriche di canali, uno per ciascun servizio). Inserisco "Cache" nell'esempio come una specie di segnaposto: sostituisci la sintassi con qualsiasi meccanismo di caching che stai utilizzando.
public static Dictionary<string, object> OpenChannels
{
get
{
if (Cache["OpenChannels"] == null)
{
Cache["OpenChannels"] = new Dictionary<string, object>();
}
return (Dictionary<string, object>)Cache["OpenChannels"];
}
set
{
Cache["OpenChannels"] = value;
}
}
Avanti è un metodo per creare un canale di comunicazione dall'istanza di fabbrica. Il metodo controlla se la fabbrica esiste prima - se non lo fa, la crea, la mette nel dizionario e poi genera il canale. In caso contrario, genera semplicemente un canale dall'istanza memorizzata nella cache della fabbrica.
public static T GetFactoryChannel<T>(string address)
{
string key = typeof(T.Name);
if (!OpenChannels.ContainsKey(key))
{
ChannelFactory<T> factory = new ChannelFactory<T>();
factory.Endpoint.Address = new EndpointAddress(new System.Uri(address));
factory.Endpoint.Binding = new BasicHttpBinding();
OpenChannels.Add(key, factory);
}
T channel = ((ChannelFactory<T>)OpenChannels[key]).CreateChannel();
((IClientChannel)channel).Open();
return channel;
}
Ho tolto questo esempio da quello che uso al lavoro. C'è molto che puoi fare con questo metodo: puoi gestire più associazioni, assegnare credenziali per l'autenticazione, ecc. È praticamente il tuo centro commerciale unico per la generazione di un cliente.
Infine, quando lo uso nell'applicazione, generalmente creo un canale, faccio il mio lavoro e lo chiudo (o lo interrompo se necessario). Ad esempio:
IMyServiceContract client;
try
{
client = Helper.GetFactoryChannel<IMyServiceContract>("http://myserviceaddress");
client.DoSomething();
// This is another helper method that will safely close the channel,
// handling any exceptions that may occurr trying to close.
// Shouldn't be any, but it doesn't hurt.
Helper.CloseChannel(client);
}
catch (Exception ex)
{
// Something went wrong; need to abort the channel
// I also do logging of some sort here
Helper.AbortChannel(client);
}
Speriamo che gli esempi sopra ti diano qualcosa da fare. Ho usato qualcosa di simile a questo per circa un anno in un ambiente di produzione e ha funzionato molto bene. Il 99% dei problemi riscontrati di solito sono stati correlati a qualcosa al di fuori dell'applicazione (client esterni o fonti di dati non sotto il nostro controllo diretto).
Fatemi sapere se qualcosa non è chiaro o avete ulteriori domande.
Per # 3, sì, è necessario creare una sola fabbrica di canali. Fondamentalmente, avrai una fabbrica di canali per ciascuno dei servizi che hai. Nel mio caso, ne abbiamo circa 6 finora, distribuiti principalmente su 2 livelli. Nel tuo caso, se hai solo intenzione di avere un servizio, utilizzare da un'app, puoi semplicemente fare quello che stai facendo sopra. Il codice sopra riportato è sulla strada giusta. Il caching sarà basato sulle esigenze dell'app. – Tim
@Tim-grazie per tutto il tuo aiuto. Lo apprezzo davvero! Penso che nel mio caso il fatto che il mio servizio fosse così "semplice" mi causava confusione nel guardare questi altri esempi dove c'erano più endpoint. Me = meno confuso ora = Tim ha fatto un ottimo lavoro spiegando! Grazie amico! – Didaxis
Sei il benvenuto. Sono contento di poterti aiutare: felice codifica! – Tim