Я пытаюсь абстрагироваться/инкапсулировать следующий код, чтобы все клиентские вызовы не нуждались в повторении этого кода. Например, это вызов, от модели представления (MVVM) к службе WCF:Tricky IDisposable Issue
using (var channelFactory = new WcfChannelFactory<IPrestoService>(new NetTcpBinding()))
{
var endpointAddress = ConfigurationManager.AppSettings["prestoServiceAddress"];
IPrestoService prestoService = channelFactory.CreateChannel(new EndpointAddress(endpointAddress));
this.Applications = new ObservableCollection<Application>(prestoService.GetAllApplications().ToList());
}
Моя первоначальная попытка рефакторинга было сделать это:
public static class PrestoWcf
{
public static IPrestoService PrestoService
{
get
{
using (var channelFactory = new WcfChannelFactory<IPrestoService>(new NetTcpBinding()))
{
var endpointAddress = ConfigurationManager.AppSettings["prestoServiceAddress"];
return channelFactory.CreateChannel(new EndpointAddress(endpointAddress));
}
}
}
}
Это позволяет мой взгляд моделей сделать вызов с помощью всего одной строки кода сейчас:
this.Applications = new ObservableCollection<Application>(PrestoWcf.PrestoService.GetAllApplications().ToList());
Однако я получаю ошибку WcfChannelFactory
уже размещенный. Это имеет смысл, потому что оно действительно используется, когда модель представления пытается его использовать. Но если я удалю using
, то я не правильно распоряжаюсь WcfChannelFactory
. Обратите внимание, что WcfChannelFactory
вставляется в WcfClientProxy
, когда вызывается CreateChannel()
. Вот почему/как модель представления пытается использовать ее после того, как она была удалена.
Как я могу абстрагироваться от этого кода, чтобы мои запросы на модели зрения были максимально простыми, при правильном размещении WcfChannelFactory
? Надеюсь, я объяснил это достаточно хорошо.
Редактировать - Решено!
Основываясь на стейки ответ, это сделал:
public static class PrestoWcf
{
public static T Invoke<T>(Func<IPrestoService, T> func)
{
using (var channelFactory = new WcfChannelFactory<IPrestoService>(new NetTcpBinding()))
{
var endpointAddress = ConfigurationManager.AppSettings["prestoServiceAddress"];
IPrestoService prestoService = channelFactory.CreateChannel(new EndpointAddress(endpointAddress));
return func(prestoService);
}
}
}
А вот вид модели вызова:
this.Applications = new ObservableCollection<Application>(PrestoWcf.Invoke(service => service.GetAllApplications()).ToList());
+1 для использования Func, который возвращает ваши приложения, а не действие с побочными эффектами! –