すべてのクライアント呼び出しでこのコードを繰り返す必要がないように、次のコードを抽象化/カプセル化しようとしています。たとえば、これはビュー モデル (MVVM) から WCF サービスへの呼び出しです。
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));
}
}
}
}
これにより、私のビュー モデルはたった 1 行のコードで呼び出しを行うことができます。
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());