WCF クライアントの作成方法を見直し

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 クラスを継承した独自のベースクラスを作成し、そのベースクラスを継承して各サービスのプロキシを作るようにすれば、共通処理をベースクラスに押し込むことも可能です。