Используйте ChannelFactory для создания экземпляра фабрики, а затем кэшируйте этот экземпляр. Затем вы можете создавать каналы связи по необходимости / по желанию из кэшированного ресурса.
Есть ли у вас потребность в фабриках с несколькими каналами (т. Е. Есть ли несколько служб)? По моему опыту, именно здесь вы увидите наибольшее преимущество в производительности. Создание канала - довольно недорогая задача; все настраивается в начале, что требует времени.
Я бы не кэшировал отдельные каналы - я бы их создал, использовал для операции, а затем закрыл. Если вы кешируете их, они могут перестать работать, и канал выйдет из строя, тогда вам придется прервать его и в любом случае создать новый.
Не уверен, почему вы хотите использовать синглтон для реализации ChannelFactory, особенно если вы собираетесь его создать и кэшировать, и есть только одна конечная точка.
Я опубликую пример кода позже, когда у меня будет немного больше времени.
ОБНОВЛЕНИЕ: Примеры кода
Вот пример того, как я реализовал это для проекта на работе. Я использовал ChannelFactory<T>
, так как приложение, которое я разрабатывал, представляет собой n-уровневое приложение с несколькими службами, и будут добавлены другие. Цель состояла в том, чтобы создать простой способ создания клиента один раз в течение жизни приложения, а затем создавать каналы связи по мере необходимости. Основы этой идеи не мои (я получил ее из статьи в Интернете), хотя я изменил реализацию для своих нужд.
В моем приложении есть статический вспомогательный класс, и в этом классе у меня есть словарь и метод для создания каналов связи из фабрики channelf.
Словарь выглядит следующим образом (объект - это значение, поскольку оно будет содержать разные фабрики каналов, по одному для каждой службы). Я поместил «Cache» в этом примере в качестве заполнителя - замените синтаксис тем механизмом кэширования, который вы используете.
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;
}
}
Далее - метод создания канала связи из заводского экземпляра. Метод проверяет, существует ли сначала фабрика - если нет, то создает ее, помещает в словарь и затем генерирует канал. В противном случае он просто генерирует канал из кэшированного экземпляра фабрики.
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;
}
Я вычеркнул этот пример из того, что я использую на работе. В этом методе вы можете многое сделать - вы можете обрабатывать несколько привязок, назначать учетные данные для аутентификации и т. Д. Это практически ваш универсальный торговый центр для генерации клиента.
Наконец, когда я использую его в приложении, я обычно создаю канал, делаю свое дело и закрываю его (или отменяю его, если это необходимо). Например:
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);
}
Надеюсь, приведенные выше примеры помогут вам продолжить. Я использую нечто похожее на это уже около года в производственной среде, и это работает очень хорошо. 99% любых проблем, с которыми мы сталкивались, обычно были связаны с чем-то вне приложения (внешними клиентами или источниками данных, которые не находятся под нашим непосредственным контролем).
Дайте мне знать, если что-то не понятно или у вас есть дополнительные вопросы.