From ddc4e346bc3a59cef38bdf3e79fb2f1940bb4df2 Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@google.com>
Date: Mon, 21 Mar 2016 19:03:14 -0700
Subject: [PATCH] regenerate code

---
 src/csharp/Grpc.Examples/MathGrpc.cs          |  69 +++---
 src/csharp/Grpc.HealthCheck/HealthGrpc.cs     |  39 ++--
 .../Grpc.IntegrationTesting/ServicesGrpc.cs   | 128 +++++++-----
 .../Grpc.IntegrationTesting/TestGrpc.cs       | 197 ++++++++++--------
 4 files changed, 246 insertions(+), 187 deletions(-)

diff --git a/src/csharp/Grpc.Examples/MathGrpc.cs b/src/csharp/Grpc.Examples/MathGrpc.cs
index ba237ddfd2..f3bb0d1cdc 100644
--- a/src/csharp/Grpc.Examples/MathGrpc.cs
+++ b/src/csharp/Grpc.Examples/MathGrpc.cs
@@ -52,6 +52,7 @@ namespace Math {
     }
 
     // client interface
+    [System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
     public interface IMathClient
     {
       global::Math.DivReply Div(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
@@ -102,60 +103,66 @@ namespace Math {
     }
 
     // client stub
-    public class MathClient : ClientBase, IMathClient
+    public class MathClient : ClientBase<MathClient>, IMathClient
     {
       public MathClient(Channel channel) : base(channel)
       {
       }
-      public global::Math.DivReply Div(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public MathClient(CallInvoker callInvoker) : base(callInvoker)
       {
-        var call = CreateCall(__Method_Div, new CallOptions(headers, deadline, cancellationToken));
-        return Calls.BlockingUnaryCall(call, request);
       }
-      public global::Math.DivReply Div(global::Math.DivArgs request, CallOptions options)
+      ///<summary>Protected parameterless constructor to allow creation of test doubles.</summary>
+      protected MathClient() : base()
       {
-        var call = CreateCall(__Method_Div, options);
-        return Calls.BlockingUnaryCall(call, request);
       }
-      public AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      ///<summary>Protected constructor to allow creation of configured clients.</summary>
+      protected MathClient(ClientBaseConfiguration configuration) : base(configuration)
       {
-        var call = CreateCall(__Method_Div, new CallOptions(headers, deadline, cancellationToken));
-        return Calls.AsyncUnaryCall(call, request);
       }
-      public AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, CallOptions options)
+
+      public virtual global::Math.DivReply Div(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      {
+        return Div(request, new CallOptions(headers, deadline, cancellationToken));
+      }
+      public virtual global::Math.DivReply Div(global::Math.DivArgs request, CallOptions options)
+      {
+        return CallInvoker.BlockingUnaryCall(__Method_Div, null, options, request);
+      }
+      public virtual AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      {
+        return DivAsync(request, new CallOptions(headers, deadline, cancellationToken));
+      }
+      public virtual AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, CallOptions options)
+      {
+        return CallInvoker.AsyncUnaryCall(__Method_Div, null, options, request);
+      }
+      public virtual AsyncDuplexStreamingCall<global::Math.DivArgs, global::Math.DivReply> DivMany(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        var call = CreateCall(__Method_Div, options);
-        return Calls.AsyncUnaryCall(call, request);
+        return DivMany(new CallOptions(headers, deadline, cancellationToken));
       }
-      public AsyncDuplexStreamingCall<global::Math.DivArgs, global::Math.DivReply> DivMany(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual AsyncDuplexStreamingCall<global::Math.DivArgs, global::Math.DivReply> DivMany(CallOptions options)
       {
-        var call = CreateCall(__Method_DivMany, new CallOptions(headers, deadline, cancellationToken));
-        return Calls.AsyncDuplexStreamingCall(call);
+        return CallInvoker.AsyncDuplexStreamingCall(__Method_DivMany, null, options);
       }
-      public AsyncDuplexStreamingCall<global::Math.DivArgs, global::Math.DivReply> DivMany(CallOptions options)
+      public virtual AsyncServerStreamingCall<global::Math.Num> Fib(global::Math.FibArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        var call = CreateCall(__Method_DivMany, options);
-        return Calls.AsyncDuplexStreamingCall(call);
+        return Fib(request, new CallOptions(headers, deadline, cancellationToken));
       }
-      public AsyncServerStreamingCall<global::Math.Num> Fib(global::Math.FibArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual AsyncServerStreamingCall<global::Math.Num> Fib(global::Math.FibArgs request, CallOptions options)
       {
-        var call = CreateCall(__Method_Fib, new CallOptions(headers, deadline, cancellationToken));
-        return Calls.AsyncServerStreamingCall(call, request);
+        return CallInvoker.AsyncServerStreamingCall(__Method_Fib, null, options, request);
       }
-      public AsyncServerStreamingCall<global::Math.Num> Fib(global::Math.FibArgs request, CallOptions options)
+      public virtual AsyncClientStreamingCall<global::Math.Num, global::Math.Num> Sum(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        var call = CreateCall(__Method_Fib, options);
-        return Calls.AsyncServerStreamingCall(call, request);
+        return Sum(new CallOptions(headers, deadline, cancellationToken));
       }
-      public AsyncClientStreamingCall<global::Math.Num, global::Math.Num> Sum(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual AsyncClientStreamingCall<global::Math.Num, global::Math.Num> Sum(CallOptions options)
       {
-        var call = CreateCall(__Method_Sum, new CallOptions(headers, deadline, cancellationToken));
-        return Calls.AsyncClientStreamingCall(call);
+        return CallInvoker.AsyncClientStreamingCall(__Method_Sum, null, options);
       }
-      public AsyncClientStreamingCall<global::Math.Num, global::Math.Num> Sum(CallOptions options)
+      protected override MathClient NewInstance(ClientBaseConfiguration configuration)
       {
-        var call = CreateCall(__Method_Sum, options);
-        return Calls.AsyncClientStreamingCall(call);
+        return new MathClient(configuration);
       }
     }
 
diff --git a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
index fffdf03be4..72e11cca3a 100644
--- a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
+++ b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
@@ -29,6 +29,7 @@ namespace Grpc.Health.V1 {
     }
 
     // client interface
+    [System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
     public interface IHealthClient
     {
       global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
@@ -55,30 +56,42 @@ namespace Grpc.Health.V1 {
     }
 
     // client stub
-    public class HealthClient : ClientBase, IHealthClient
+    public class HealthClient : ClientBase<HealthClient>, IHealthClient
     {
       public HealthClient(Channel channel) : base(channel)
       {
       }
-      public global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public HealthClient(CallInvoker callInvoker) : base(callInvoker)
       {
-        var call = CreateCall(__Method_Check, new CallOptions(headers, deadline, cancellationToken));
-        return Calls.BlockingUnaryCall(call, request);
       }
-      public global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, CallOptions options)
+      ///<summary>Protected parameterless constructor to allow creation of test doubles.</summary>
+      protected HealthClient() : base()
       {
-        var call = CreateCall(__Method_Check, options);
-        return Calls.BlockingUnaryCall(call, request);
       }
-      public AsyncUnaryCall<global::Grpc.Health.V1.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      ///<summary>Protected constructor to allow creation of configured clients.</summary>
+      protected HealthClient(ClientBaseConfiguration configuration) : base(configuration)
       {
-        var call = CreateCall(__Method_Check, new CallOptions(headers, deadline, cancellationToken));
-        return Calls.AsyncUnaryCall(call, request);
       }
-      public AsyncUnaryCall<global::Grpc.Health.V1.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1.HealthCheckRequest request, CallOptions options)
+
+      public virtual global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      {
+        return Check(request, new CallOptions(headers, deadline, cancellationToken));
+      }
+      public virtual global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, CallOptions options)
+      {
+        return CallInvoker.BlockingUnaryCall(__Method_Check, null, options, request);
+      }
+      public virtual AsyncUnaryCall<global::Grpc.Health.V1.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      {
+        return CheckAsync(request, new CallOptions(headers, deadline, cancellationToken));
+      }
+      public virtual AsyncUnaryCall<global::Grpc.Health.V1.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1.HealthCheckRequest request, CallOptions options)
+      {
+        return CallInvoker.AsyncUnaryCall(__Method_Check, null, options, request);
+      }
+      protected override HealthClient NewInstance(ClientBaseConfiguration configuration)
       {
-        var call = CreateCall(__Method_Check, options);
-        return Calls.AsyncUnaryCall(call, request);
+        return new HealthClient(configuration);
       }
     }
 
diff --git a/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs b/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
index beffa2298d..46b16cf202 100644
--- a/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
@@ -36,6 +36,7 @@ namespace Grpc.Testing {
     }
 
     // client interface
+    [System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
     public interface IBenchmarkServiceClient
     {
       global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
@@ -70,40 +71,50 @@ namespace Grpc.Testing {
     }
 
     // client stub
-    public class BenchmarkServiceClient : ClientBase, IBenchmarkServiceClient
+    public class BenchmarkServiceClient : ClientBase<BenchmarkServiceClient>, IBenchmarkServiceClient
     {
       public BenchmarkServiceClient(Channel channel) : base(channel)
       {
       }
-      public global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public BenchmarkServiceClient(CallInvoker callInvoker) : base(callInvoker)
       {
-        var call = CreateCall(__Method_UnaryCall, new CallOptions(headers, deadline, cancellationToken));
-        return Calls.BlockingUnaryCall(call, request);
       }
-      public global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, CallOptions options)
+      ///<summary>Protected parameterless constructor to allow creation of test doubles.</summary>
+      protected BenchmarkServiceClient() : base()
       {
-        var call = CreateCall(__Method_UnaryCall, options);
-        return Calls.BlockingUnaryCall(call, request);
       }
-      public AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      ///<summary>Protected constructor to allow creation of configured clients.</summary>
+      protected BenchmarkServiceClient(ClientBaseConfiguration configuration) : base(configuration)
       {
-        var call = CreateCall(__Method_UnaryCall, new CallOptions(headers, deadline, cancellationToken));
-        return Calls.AsyncUnaryCall(call, request);
       }
-      public AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, CallOptions options)
+
+      public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      {
+        return UnaryCall(request, new CallOptions(headers, deadline, cancellationToken));
+      }
+      public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, CallOptions options)
+      {
+        return CallInvoker.BlockingUnaryCall(__Method_UnaryCall, null, options, request);
+      }
+      public virtual AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      {
+        return UnaryCallAsync(request, new CallOptions(headers, deadline, cancellationToken));
+      }
+      public virtual AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, CallOptions options)
+      {
+        return CallInvoker.AsyncUnaryCall(__Method_UnaryCall, null, options, request);
+      }
+      public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        var call = CreateCall(__Method_UnaryCall, options);
-        return Calls.AsyncUnaryCall(call, request);
+        return StreamingCall(new CallOptions(headers, deadline, cancellationToken));
       }
-      public AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(CallOptions options)
       {
-        var call = CreateCall(__Method_StreamingCall, new CallOptions(headers, deadline, cancellationToken));
-        return Calls.AsyncDuplexStreamingCall(call);
+        return CallInvoker.AsyncDuplexStreamingCall(__Method_StreamingCall, null, options);
       }
-      public AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(CallOptions options)
+      protected override BenchmarkServiceClient NewInstance(ClientBaseConfiguration configuration)
       {
-        var call = CreateCall(__Method_StreamingCall, options);
-        return Calls.AsyncDuplexStreamingCall(call);
+        return new BenchmarkServiceClient(configuration);
       }
     }
 
@@ -177,6 +188,7 @@ namespace Grpc.Testing {
     }
 
     // client interface
+    [System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
     public interface IWorkerServiceClient
     {
       AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
@@ -229,70 +241,74 @@ namespace Grpc.Testing {
     }
 
     // client stub
-    public class WorkerServiceClient : ClientBase, IWorkerServiceClient
+    public class WorkerServiceClient : ClientBase<WorkerServiceClient>, IWorkerServiceClient
     {
       public WorkerServiceClient(Channel channel) : base(channel)
       {
       }
-      public AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public WorkerServiceClient(CallInvoker callInvoker) : base(callInvoker)
+      {
+      }
+      ///<summary>Protected parameterless constructor to allow creation of test doubles.</summary>
+      protected WorkerServiceClient() : base()
+      {
+      }
+      ///<summary>Protected constructor to allow creation of configured clients.</summary>
+      protected WorkerServiceClient(ClientBaseConfiguration configuration) : base(configuration)
+      {
+      }
+
+      public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      {
+        return RunServer(new CallOptions(headers, deadline, cancellationToken));
+      }
+      public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(CallOptions options)
       {
-        var call = CreateCall(__Method_RunServer, new CallOptions(headers, deadline, cancellationToken));
-        return Calls.AsyncDuplexStreamingCall(call);
+        return CallInvoker.AsyncDuplexStreamingCall(__Method_RunServer, null, options);
       }
-      public AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(CallOptions options)
+      public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        var call = CreateCall(__Method_RunServer, options);
-        return Calls.AsyncDuplexStreamingCall(call);
+        return RunClient(new CallOptions(headers, deadline, cancellationToken));
       }
-      public AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(CallOptions options)
       {
-        var call = CreateCall(__Method_RunClient, new CallOptions(headers, deadline, cancellationToken));
-        return Calls.AsyncDuplexStreamingCall(call);
+        return CallInvoker.AsyncDuplexStreamingCall(__Method_RunClient, null, options);
       }
-      public AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(CallOptions options)
+      public virtual global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        var call = CreateCall(__Method_RunClient, options);
-        return Calls.AsyncDuplexStreamingCall(call);
+        return CoreCount(request, new CallOptions(headers, deadline, cancellationToken));
       }
-      public global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, CallOptions options)
       {
-        var call = CreateCall(__Method_CoreCount, new CallOptions(headers, deadline, cancellationToken));
-        return Calls.BlockingUnaryCall(call, request);
+        return CallInvoker.BlockingUnaryCall(__Method_CoreCount, null, options, request);
       }
-      public global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, CallOptions options)
+      public virtual AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        var call = CreateCall(__Method_CoreCount, options);
-        return Calls.BlockingUnaryCall(call, request);
+        return CoreCountAsync(request, new CallOptions(headers, deadline, cancellationToken));
       }
-      public AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, CallOptions options)
       {
-        var call = CreateCall(__Method_CoreCount, new CallOptions(headers, deadline, cancellationToken));
-        return Calls.AsyncUnaryCall(call, request);
+        return CallInvoker.AsyncUnaryCall(__Method_CoreCount, null, options, request);
       }
-      public AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, CallOptions options)
+      public virtual global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        var call = CreateCall(__Method_CoreCount, options);
-        return Calls.AsyncUnaryCall(call, request);
+        return QuitWorker(request, new CallOptions(headers, deadline, cancellationToken));
       }
-      public global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, CallOptions options)
       {
-        var call = CreateCall(__Method_QuitWorker, new CallOptions(headers, deadline, cancellationToken));
-        return Calls.BlockingUnaryCall(call, request);
+        return CallInvoker.BlockingUnaryCall(__Method_QuitWorker, null, options, request);
       }
-      public global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, CallOptions options)
+      public virtual AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        var call = CreateCall(__Method_QuitWorker, options);
-        return Calls.BlockingUnaryCall(call, request);
+        return QuitWorkerAsync(request, new CallOptions(headers, deadline, cancellationToken));
       }
-      public AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, CallOptions options)
       {
-        var call = CreateCall(__Method_QuitWorker, new CallOptions(headers, deadline, cancellationToken));
-        return Calls.AsyncUnaryCall(call, request);
+        return CallInvoker.AsyncUnaryCall(__Method_QuitWorker, null, options, request);
       }
-      public AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, CallOptions options)
+      protected override WorkerServiceClient NewInstance(ClientBaseConfiguration configuration)
       {
-        var call = CreateCall(__Method_QuitWorker, options);
-        return Calls.AsyncUnaryCall(call, request);
+        return new WorkerServiceClient(configuration);
       }
     }
 
diff --git a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
index 6b3a7cbf2d..b84ec2d984 100644
--- a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
@@ -69,6 +69,7 @@ namespace Grpc.Testing {
     }
 
     // client interface
+    [System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
     public interface ITestServiceClient
     {
       global::Grpc.Testing.Empty EmptyCall(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
@@ -137,90 +138,90 @@ namespace Grpc.Testing {
     }
 
     // client stub
-    public class TestServiceClient : ClientBase, ITestServiceClient
+    public class TestServiceClient : ClientBase<TestServiceClient>, ITestServiceClient
     {
       public TestServiceClient(Channel channel) : base(channel)
       {
       }
-      public global::Grpc.Testing.Empty EmptyCall(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public TestServiceClient(CallInvoker callInvoker) : base(callInvoker)
       {
-        var call = CreateCall(__Method_EmptyCall, new CallOptions(headers, deadline, cancellationToken));
-        return Calls.BlockingUnaryCall(call, request);
       }
-      public global::Grpc.Testing.Empty EmptyCall(global::Grpc.Testing.Empty request, CallOptions options)
+      ///<summary>Protected parameterless constructor to allow creation of test doubles.</summary>
+      protected TestServiceClient() : base()
       {
-        var call = CreateCall(__Method_EmptyCall, options);
-        return Calls.BlockingUnaryCall(call, request);
       }
-      public AsyncUnaryCall<global::Grpc.Testing.Empty> EmptyCallAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      ///<summary>Protected constructor to allow creation of configured clients.</summary>
+      protected TestServiceClient(ClientBaseConfiguration configuration) : base(configuration)
       {
-        var call = CreateCall(__Method_EmptyCall, new CallOptions(headers, deadline, cancellationToken));
-        return Calls.AsyncUnaryCall(call, request);
       }
-      public AsyncUnaryCall<global::Grpc.Testing.Empty> EmptyCallAsync(global::Grpc.Testing.Empty request, CallOptions options)
+
+      public virtual global::Grpc.Testing.Empty EmptyCall(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      {
+        return EmptyCall(request, new CallOptions(headers, deadline, cancellationToken));
+      }
+      public virtual global::Grpc.Testing.Empty EmptyCall(global::Grpc.Testing.Empty request, CallOptions options)
+      {
+        return CallInvoker.BlockingUnaryCall(__Method_EmptyCall, null, options, request);
+      }
+      public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> EmptyCallAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      {
+        return EmptyCallAsync(request, new CallOptions(headers, deadline, cancellationToken));
+      }
+      public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> EmptyCallAsync(global::Grpc.Testing.Empty request, CallOptions options)
       {
-        var call = CreateCall(__Method_EmptyCall, options);
-        return Calls.AsyncUnaryCall(call, request);
+        return CallInvoker.AsyncUnaryCall(__Method_EmptyCall, null, options, request);
       }
-      public global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        var call = CreateCall(__Method_UnaryCall, new CallOptions(headers, deadline, cancellationToken));
-        return Calls.BlockingUnaryCall(call, request);
+        return UnaryCall(request, new CallOptions(headers, deadline, cancellationToken));
       }
-      public global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, CallOptions options)
+      public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, CallOptions options)
       {
-        var call = CreateCall(__Method_UnaryCall, options);
-        return Calls.BlockingUnaryCall(call, request);
+        return CallInvoker.BlockingUnaryCall(__Method_UnaryCall, null, options, request);
       }
-      public AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        var call = CreateCall(__Method_UnaryCall, new CallOptions(headers, deadline, cancellationToken));
-        return Calls.AsyncUnaryCall(call, request);
+        return UnaryCallAsync(request, new CallOptions(headers, deadline, cancellationToken));
       }
-      public AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, CallOptions options)
+      public virtual AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, CallOptions options)
       {
-        var call = CreateCall(__Method_UnaryCall, options);
-        return Calls.AsyncUnaryCall(call, request);
+        return CallInvoker.AsyncUnaryCall(__Method_UnaryCall, null, options, request);
       }
-      public AsyncServerStreamingCall<global::Grpc.Testing.StreamingOutputCallResponse> StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual AsyncServerStreamingCall<global::Grpc.Testing.StreamingOutputCallResponse> StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        var call = CreateCall(__Method_StreamingOutputCall, new CallOptions(headers, deadline, cancellationToken));
-        return Calls.AsyncServerStreamingCall(call, request);
+        return StreamingOutputCall(request, new CallOptions(headers, deadline, cancellationToken));
       }
-      public AsyncServerStreamingCall<global::Grpc.Testing.StreamingOutputCallResponse> StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, CallOptions options)
+      public virtual AsyncServerStreamingCall<global::Grpc.Testing.StreamingOutputCallResponse> StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, CallOptions options)
       {
-        var call = CreateCall(__Method_StreamingOutputCall, options);
-        return Calls.AsyncServerStreamingCall(call, request);
+        return CallInvoker.AsyncServerStreamingCall(__Method_StreamingOutputCall, null, options, request);
       }
-      public AsyncClientStreamingCall<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual AsyncClientStreamingCall<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        var call = CreateCall(__Method_StreamingInputCall, new CallOptions(headers, deadline, cancellationToken));
-        return Calls.AsyncClientStreamingCall(call);
+        return StreamingInputCall(new CallOptions(headers, deadline, cancellationToken));
       }
-      public AsyncClientStreamingCall<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(CallOptions options)
+      public virtual AsyncClientStreamingCall<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(CallOptions options)
       {
-        var call = CreateCall(__Method_StreamingInputCall, options);
-        return Calls.AsyncClientStreamingCall(call);
+        return CallInvoker.AsyncClientStreamingCall(__Method_StreamingInputCall, null, options);
       }
-      public AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> FullDuplexCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> FullDuplexCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        var call = CreateCall(__Method_FullDuplexCall, new CallOptions(headers, deadline, cancellationToken));
-        return Calls.AsyncDuplexStreamingCall(call);
+        return FullDuplexCall(new CallOptions(headers, deadline, cancellationToken));
       }
-      public AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> FullDuplexCall(CallOptions options)
+      public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> FullDuplexCall(CallOptions options)
       {
-        var call = CreateCall(__Method_FullDuplexCall, options);
-        return Calls.AsyncDuplexStreamingCall(call);
+        return CallInvoker.AsyncDuplexStreamingCall(__Method_FullDuplexCall, null, options);
       }
-      public AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> HalfDuplexCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> HalfDuplexCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        var call = CreateCall(__Method_HalfDuplexCall, new CallOptions(headers, deadline, cancellationToken));
-        return Calls.AsyncDuplexStreamingCall(call);
+        return HalfDuplexCall(new CallOptions(headers, deadline, cancellationToken));
       }
-      public AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> HalfDuplexCall(CallOptions options)
+      public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> HalfDuplexCall(CallOptions options)
       {
-        var call = CreateCall(__Method_HalfDuplexCall, options);
-        return Calls.AsyncDuplexStreamingCall(call);
+        return CallInvoker.AsyncDuplexStreamingCall(__Method_HalfDuplexCall, null, options);
+      }
+      protected override TestServiceClient NewInstance(ClientBaseConfiguration configuration)
+      {
+        return new TestServiceClient(configuration);
       }
     }
 
@@ -275,6 +276,7 @@ namespace Grpc.Testing {
     }
 
     // client interface
+    [System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
     public interface IUnimplementedServiceClient
     {
       global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
@@ -301,30 +303,42 @@ namespace Grpc.Testing {
     }
 
     // client stub
-    public class UnimplementedServiceClient : ClientBase, IUnimplementedServiceClient
+    public class UnimplementedServiceClient : ClientBase<UnimplementedServiceClient>, IUnimplementedServiceClient
     {
       public UnimplementedServiceClient(Channel channel) : base(channel)
       {
       }
-      public global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public UnimplementedServiceClient(CallInvoker callInvoker) : base(callInvoker)
+      {
+      }
+      ///<summary>Protected parameterless constructor to allow creation of test doubles.</summary>
+      protected UnimplementedServiceClient() : base()
       {
-        var call = CreateCall(__Method_UnimplementedCall, new CallOptions(headers, deadline, cancellationToken));
-        return Calls.BlockingUnaryCall(call, request);
       }
-      public global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, CallOptions options)
+      ///<summary>Protected constructor to allow creation of configured clients.</summary>
+      protected UnimplementedServiceClient(ClientBaseConfiguration configuration) : base(configuration)
+      {
+      }
+
+      public virtual global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        var call = CreateCall(__Method_UnimplementedCall, options);
-        return Calls.BlockingUnaryCall(call, request);
+        return UnimplementedCall(request, new CallOptions(headers, deadline, cancellationToken));
       }
-      public AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, CallOptions options)
       {
-        var call = CreateCall(__Method_UnimplementedCall, new CallOptions(headers, deadline, cancellationToken));
-        return Calls.AsyncUnaryCall(call, request);
+        return CallInvoker.BlockingUnaryCall(__Method_UnimplementedCall, null, options, request);
       }
-      public AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, CallOptions options)
+      public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        var call = CreateCall(__Method_UnimplementedCall, options);
-        return Calls.AsyncUnaryCall(call, request);
+        return UnimplementedCallAsync(request, new CallOptions(headers, deadline, cancellationToken));
+      }
+      public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, CallOptions options)
+      {
+        return CallInvoker.AsyncUnaryCall(__Method_UnimplementedCall, null, options, request);
+      }
+      protected override UnimplementedServiceClient NewInstance(ClientBaseConfiguration configuration)
+      {
+        return new UnimplementedServiceClient(configuration);
       }
     }
 
@@ -377,6 +391,7 @@ namespace Grpc.Testing {
     }
 
     // client interface
+    [System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
     public interface IReconnectServiceClient
     {
       global::Grpc.Testing.Empty Start(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
@@ -413,50 +428,58 @@ namespace Grpc.Testing {
     }
 
     // client stub
-    public class ReconnectServiceClient : ClientBase, IReconnectServiceClient
+    public class ReconnectServiceClient : ClientBase<ReconnectServiceClient>, IReconnectServiceClient
     {
       public ReconnectServiceClient(Channel channel) : base(channel)
       {
       }
-      public global::Grpc.Testing.Empty Start(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public ReconnectServiceClient(CallInvoker callInvoker) : base(callInvoker)
+      {
+      }
+      ///<summary>Protected parameterless constructor to allow creation of test doubles.</summary>
+      protected ReconnectServiceClient() : base()
+      {
+      }
+      ///<summary>Protected constructor to allow creation of configured clients.</summary>
+      protected ReconnectServiceClient(ClientBaseConfiguration configuration) : base(configuration)
+      {
+      }
+
+      public virtual global::Grpc.Testing.Empty Start(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      {
+        return Start(request, new CallOptions(headers, deadline, cancellationToken));
+      }
+      public virtual global::Grpc.Testing.Empty Start(global::Grpc.Testing.Empty request, CallOptions options)
       {
-        var call = CreateCall(__Method_Start, new CallOptions(headers, deadline, cancellationToken));
-        return Calls.BlockingUnaryCall(call, request);
+        return CallInvoker.BlockingUnaryCall(__Method_Start, null, options, request);
       }
-      public global::Grpc.Testing.Empty Start(global::Grpc.Testing.Empty request, CallOptions options)
+      public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> StartAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        var call = CreateCall(__Method_Start, options);
-        return Calls.BlockingUnaryCall(call, request);
+        return StartAsync(request, new CallOptions(headers, deadline, cancellationToken));
       }
-      public AsyncUnaryCall<global::Grpc.Testing.Empty> StartAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> StartAsync(global::Grpc.Testing.Empty request, CallOptions options)
       {
-        var call = CreateCall(__Method_Start, new CallOptions(headers, deadline, cancellationToken));
-        return Calls.AsyncUnaryCall(call, request);
+        return CallInvoker.AsyncUnaryCall(__Method_Start, null, options, request);
       }
-      public AsyncUnaryCall<global::Grpc.Testing.Empty> StartAsync(global::Grpc.Testing.Empty request, CallOptions options)
+      public virtual global::Grpc.Testing.ReconnectInfo Stop(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        var call = CreateCall(__Method_Start, options);
-        return Calls.AsyncUnaryCall(call, request);
+        return Stop(request, new CallOptions(headers, deadline, cancellationToken));
       }
-      public global::Grpc.Testing.ReconnectInfo Stop(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual global::Grpc.Testing.ReconnectInfo Stop(global::Grpc.Testing.Empty request, CallOptions options)
       {
-        var call = CreateCall(__Method_Stop, new CallOptions(headers, deadline, cancellationToken));
-        return Calls.BlockingUnaryCall(call, request);
+        return CallInvoker.BlockingUnaryCall(__Method_Stop, null, options, request);
       }
-      public global::Grpc.Testing.ReconnectInfo Stop(global::Grpc.Testing.Empty request, CallOptions options)
+      public virtual AsyncUnaryCall<global::Grpc.Testing.ReconnectInfo> StopAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
-        var call = CreateCall(__Method_Stop, options);
-        return Calls.BlockingUnaryCall(call, request);
+        return StopAsync(request, new CallOptions(headers, deadline, cancellationToken));
       }
-      public AsyncUnaryCall<global::Grpc.Testing.ReconnectInfo> StopAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual AsyncUnaryCall<global::Grpc.Testing.ReconnectInfo> StopAsync(global::Grpc.Testing.Empty request, CallOptions options)
       {
-        var call = CreateCall(__Method_Stop, new CallOptions(headers, deadline, cancellationToken));
-        return Calls.AsyncUnaryCall(call, request);
+        return CallInvoker.AsyncUnaryCall(__Method_Stop, null, options, request);
       }
-      public AsyncUnaryCall<global::Grpc.Testing.ReconnectInfo> StopAsync(global::Grpc.Testing.Empty request, CallOptions options)
+      protected override ReconnectServiceClient NewInstance(ClientBaseConfiguration configuration)
       {
-        var call = CreateCall(__Method_Stop, options);
-        return Calls.AsyncUnaryCall(call, request);
+        return new ReconnectServiceClient(configuration);
       }
     }
 
-- 
GitLab