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