Svcutil.exe を使ってコード生成せずに WCF クライアントを作成するとき、いつも次のようにしていました。
var client = ChannelFactory<ICustomerService>.CreateChannel( new NetTcpBinding(), new EndpointAddress("")); var result = client.GetCustomer("0001"); ((IChannel)result).Close();
簡単なサンプルならこれでいいんですが、ちゃんとしたプロジェクトの場合、エンドポイントが決め打ちになってしまうので工夫が必要です。この部分を作り込むのは面倒。
そんな中、ClientBase クラスを継承して独自に Client クラスを作成すれば再利用できることに今頃気がつきました。
public class CustomerServiceClient : ClientBase<ICustomerService>, ICustomerService { #region コンストラクタ public CustomerServiceClient() { } public CustomerServiceClient(InstanceContext callbackInstance) : base(callbackInstance) { } public CustomerServiceClient(string endpointConfigurationName) : base(endpointConfigurationName) { } public CustomerServiceClient(Binding binding, EndpointAddress remoteAddress) : base(binding, remoteAddress) { } public CustomerServiceClient(InstanceContext callbackInstance, string endpointConfigurationName) : base(callbackInstance, endpointConfigurationName) { } public CustomerServiceClient(string endpointConfigurationName, EndpointAddress remoteAddress) : base(endpointConfigurationName, remoteAddress) { } public CustomerServiceClient(string endpointConfigurationName, string remoteAddress) : base(endpointConfigurationName, remoteAddress) { } public CustomerServiceClient(InstanceContext callbackInstance, Binding binding, EndpointAddress remoteAddress) : base(callbackInstance, binding, remoteAddress) { } public CustomerServiceClient(InstanceContext callbackInstance, string endpointConfigurationName, EndpointAddress remoteAddress) : base(callbackInstance, endpointConfigurationName, remoteAddress) { } public CustomerServiceClient(InstanceContext callbackInstance, string endpointConfigurationName, string remoteAddress) : base(callbackInstance, endpointConfigurationName, remoteAddress) { } #endregion #region ICustomerService メンバ public Customer GetCustomer(string code) { return Channel.GetCustomer(code); } #endregion }
これならエンドポイントをコードと構成ファイルの両方で指定できます。
ClientBase クラスを継承した独自のベースクラスを作成し、そのベースクラスを継承して各サービスのプロキシを作るようにすれば、共通処理をベースクラスに押し込むことも可能です。