użyć ChannelFactory, aby utworzyć instancję fabryki, a następnie buforować tę instancję. Następnie można utworzyć kanały komunikacyjne zgodnie z potrzebami/pożądaniami z pamięci podręcznej.
Czy potrzebujesz wielu fabryk kanału (np. Czy jest wiele usług)? Z mojego doświadczenia wynika, że największe korzyści z wydajności mają. Utworzenie kanału jest dość niedrogim zadaniem; ustawia wszystko na początku, co wymaga czasu.
Nie będę buforował poszczególnych kanałów - będę je tworzyć, używać ich do operacji, a następnie je zamykać. Jeśli je buforujesz, mogą upłynąć limit czasu, a kanał popełni błąd, a następnie musisz go przerwać i utworzyć nowy.
Nie wiem, dlaczego chcesz zastosować singleton do implementacji ChannelFactory, zwłaszcza jeśli zamierzasz go utworzyć i wstawić do pamięci podręcznej, a jest tylko jeden punkt końcowy.
Opublikuję przykładowy kod później, gdy będę miał nieco więcej czasu.
UPDATE: Kod Przykłady
Oto przykład, jak ja to realizowane za projekt w pracy. Użyłem ChannelFactory<T>
, ponieważ aplikacja, którą tworzyłem, jest aplikacją n-warstwową z kilkoma usługami, a kolejne zostaną dodane. Celem było stworzenie prostego sposobu na utworzenie klienta raz w życiu, a następnie tworzenie kanałów komunikacji w razie potrzeby. Podstawy tego pomysłu nie są moje (otrzymałem je z artykułu w Internecie), choć zmodyfikowałem implementację do moich potrzeb.
Mam statyczną klasę pomocniczą w mojej aplikacji, aw jej obrębie mam słownik i metodę tworzenia kanałów komunikacyjnych z fabryki channelf.
Słownik jest następujący (obiekt jest wartością, ponieważ będzie zawierał różne fabryki kanałów, po jednym dla każdej usługi). Wstawiam "Pamięć podręczna" w przykładzie jako rodzaj elementu zastępczego - zamień składnię na dowolny mechanizm buforowania, którego używasz.
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;
}
}
Dalej jest metoda tworzenia kanału komunikacji z instancji fabryki. Metoda sprawdza, czy fabryka istnieje najpierw - jeśli nie, tworzy ją, umieszcza w słowniku, a następnie generuje kanał. W przeciwnym razie po prostu generuje kanał z buforowanej instancji fabryki.
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;
}
Usunąłem ten przykład z tego, z czego korzystam w pracy. W tej metodzie można wiele zrobić - można obsługiwać wiele powiązań, przypisać poświadczenia do uwierzytelniania itp. Jest to prawie jedno centrum zakupowe do generowania klienta.
Wreszcie, kiedy używam go w aplikacji, generalnie utworzę kanał, wykonam swoją działalność i zamknę (lub przerwam jeśli zajdzie taka potrzeba). Na przykład:
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);
}
Mam nadzieję, że powyższe przykłady dadzą ci coś do zrobienia. Używam czegoś podobnego od około roku w środowisku produkcyjnym i działa bardzo dobrze. 99% wszystkich napotkanych problemów zwykle dotyczyło czegoś spoza aplikacji (klientów zewnętrznych lub źródeł danych nie będących pod naszą bezpośrednią kontrolą).
Daj mi znać, jeśli coś nie jest jasne lub masz dodatkowe pytania.
Dla numeru 3 należy utworzyć tylko jedną fabrykę kanałów. Zasadniczo, będziesz mieć fabrykę jednego kanału dla każdej usługi endpiont, którą masz. W moim przypadku mamy około 6 dotychczasowych, rozłożonych głównie na 2 poziomach. W twoim przypadku, jeśli masz tylko jedną usługę, której używa jedna aplikacja, możesz po prostu zrobić to, co robisz powyżej. Powyższy kod jest na dobrej drodze. Buforowanie będzie oparte na potrzebach aplikacji. – Tim
@Tim-podziękowania za całą pomoc. Naprawdę to doceniam! Wydaje mi się, że w moim przypadku fakt, że moja usługa była tak "prosta" powodował, że nie mogłem pomylić się z innymi przykładami, w których było wiele punktów końcowych. Ja = mniej zmieszany teraz = Tim świetnie się spisał! Dzięki stary! – Didaxis
Nie ma za co. Cieszę się, że mogłem pomóc - szczęśliwe kodowanie! – Tim