diff --git a/src/compiler/csharp_generator.cc b/src/compiler/csharp_generator.cc
index 13432334231869fa01cdd6ffe38a7029caf58438..a83290af124a73423105c151bd2e4264e0e089da 100644
--- a/src/compiler/csharp_generator.cc
+++ b/src/compiler/csharp_generator.cc
@@ -363,11 +363,18 @@ void GenerateClientStub(Printer* out, const ServiceDescriptor *service) {
              "name", GetClientClassName(service));
   out->Print("{\n");
   out->Print("}\n");
-  out->Print("///<summary>Parameterless constructor to allow creation"
+  out->Print("///<summary>Protected parameterless constructor to allow creation"
              " of test doubles.</summary>\n");
   out->Print("protected $name$() : base()\n",
              "name", GetClientClassName(service));
   out->Print("{\n");
+  out->Print("}\n");
+  out->Print("///<summary>Protected constructor to allow creation of configured"
+             " clients.</summary>\n");
+  out->Print("protected $name$(ClientBaseConfiguration configuration)"
+             " : base(configuration)\n",
+             "name", GetClientClassName(service));
+  out->Print("{\n");
   out->Print("}\n\n");
 
   for (int i = 0; i < service->method_count(); i++) {
@@ -452,11 +459,11 @@ void GenerateClientStub(Printer* out, const ServiceDescriptor *service) {
   }
 
   // override NewInstance method
-  out->Print("protected override $name$ NewInstance(CallInvoker callInvoker)\n",
+  out->Print("protected override $name$ NewInstance(ClientBaseConfiguration configuration)\n",
              "name", GetClientClassName(service));
   out->Print("{\n");
   out->Indent();
-  out->Print("return new $name$(callInvoker);\n",
+  out->Print("return new $name$(configuration);\n",
              "name", GetClientClassName(service));
   out->Outdent();
   out->Print("}\n");
diff --git a/src/csharp/Grpc.Core/ClientBase.cs b/src/csharp/Grpc.Core/ClientBase.cs
index b21d01c5e2957e061efda0a4b00cb821e417e01b..e2e47893cc3dbf1dc976964c22a0a44c9f384689 100644
--- a/src/csharp/Grpc.Core/ClientBase.cs
+++ b/src/csharp/Grpc.Core/ClientBase.cs
@@ -31,9 +31,6 @@
 
 #endregion
 
-using System;
-using System.Text.RegularExpressions;
-using System.Threading.Tasks;
 using Grpc.Core.Internal;
 using Grpc.Core.Utils;
 
@@ -55,6 +52,14 @@ namespace Grpc.Core
         {
         }
 
+        /// <summary>
+        /// Initializes a new instance of <c>ClientBase</c> class.
+        /// </summary>
+        /// <param name="configuration">The configuration.</param>
+        protected ClientBase(ClientBaseConfiguration configuration) : base(configuration)
+        {
+        }
+
         /// <summary>
         /// Initializes a new instance of <c>ClientBase</c> class.
         /// </summary>
@@ -79,15 +84,14 @@ namespace Grpc.Core
         /// </summary>
         public T WithHost(string host)
         {
-            GrpcPreconditions.CheckNotNull(host, "host");
-            var decoratedInvoker = new InterceptingCallInvoker(CallInvoker, hostInterceptor: (h) => host);
-            return NewInstance(decoratedInvoker);
+            var newConfiguration = this.Configuration.WithHost(host);
+            return NewInstance(newConfiguration);
         }
 
         /// <summary>
-        /// Creates a new instance of client from given <c>CallInvoker</c>.
+        /// Creates a new instance of client from given <c>ClientBaseConfiguration</c>.
         /// </summary>
-        protected abstract T NewInstance(CallInvoker callInvoker);
+        protected abstract T NewInstance(ClientBaseConfiguration configuration);
     }
 
     /// <summary>
@@ -95,6 +99,7 @@ namespace Grpc.Core
     /// </summary>
     public abstract class ClientBase
     {
+        readonly ClientBaseConfiguration configuration;
         readonly CallInvoker callInvoker;
 
         /// <summary>
@@ -107,6 +112,16 @@ namespace Grpc.Core
         {
         }
 
+        /// <summary>
+        /// Initializes a new instance of <c>ClientBase</c> class.
+        /// </summary>
+        /// <param name="configuration">The configuration.</param>
+        protected ClientBase(ClientBaseConfiguration configuration)
+        {
+            this.configuration = GrpcPreconditions.CheckNotNull(configuration, "configuration");
+            this.callInvoker = configuration.CreateDecoratedCallInvoker();
+        }
+
         /// <summary>
         /// Initializes a new instance of <c>ClientBase</c> class.
         /// </summary>
@@ -119,9 +134,8 @@ namespace Grpc.Core
         /// Initializes a new instance of <c>ClientBase</c> class.
         /// </summary>
         /// <param name="callInvoker">The <c>CallInvoker</c> for remote call invocation.</param>
-        public ClientBase(CallInvoker callInvoker)
+        public ClientBase(CallInvoker callInvoker) : this(new ClientBaseConfiguration(callInvoker, null))
         {
-            this.callInvoker = GrpcPreconditions.CheckNotNull(callInvoker);
         }
 
         /// <summary>
@@ -131,5 +145,42 @@ namespace Grpc.Core
         {
             get { return this.callInvoker; }
         }
+
+        /// <summary>
+        /// Gets the configuration.
+        /// </summary>
+        internal ClientBaseConfiguration Configuration
+        {
+            get { return this.configuration; }
+        }
+
+        /// <summary>
+        /// Represents configuration of ClientBase. The class itself is visible to
+        /// subclasses, but contents are marked as internal to make the instances opaque.
+        /// The verbose name of this class was chosen to make name clash in generated code 
+        /// less likely.
+        /// </summary>
+        protected internal class ClientBaseConfiguration
+        {
+            readonly CallInvoker undecoratedCallInvoker;
+            readonly string host;
+
+            internal ClientBaseConfiguration(CallInvoker undecoratedCallInvoker, string host)
+            {
+                this.undecoratedCallInvoker = GrpcPreconditions.CheckNotNull(undecoratedCallInvoker);
+                this.host = host;
+            }
+
+            internal CallInvoker CreateDecoratedCallInvoker()
+            {
+                return new InterceptingCallInvoker(undecoratedCallInvoker, hostInterceptor: (h) => host);
+            }
+
+            internal ClientBaseConfiguration WithHost(string host)
+            {
+                GrpcPreconditions.CheckNotNull(host, "host");
+                return new ClientBaseConfiguration(this.undecoratedCallInvoker, host);
+            }
+        }
     }
 }
diff --git a/src/csharp/Grpc.Core/Internal/InterceptingCallInvoker.cs b/src/csharp/Grpc.Core/Internal/InterceptingCallInvoker.cs
index 1b8c54a6da27565e4058eb0bc76c3c9e13aff8d9..53569760aca92c75105f085780351ef06580641c 100644
--- a/src/csharp/Grpc.Core/Internal/InterceptingCallInvoker.cs
+++ b/src/csharp/Grpc.Core/Internal/InterceptingCallInvoker.cs
@@ -50,7 +50,6 @@ namespace Grpc.Core.Internal
         /// <summary>
         /// Initializes a new instance of the <see cref="Grpc.Core.InterceptingCallInvoker"/> class.
         /// </summary>
-        /// <param name="callInvoker">CallInvoker to decorate.</param>
         public InterceptingCallInvoker(CallInvoker callInvoker,
             Func<string, string> hostInterceptor = null,
             Func<CallOptions, CallOptions> callOptionsInterceptor = null)
@@ -116,8 +115,7 @@ namespace Grpc.Core.Internal
 
         private string InterceptHost(string host)
         {
-            // only set host if not already set to support composing interceptors.
-            if (hostInterceptor == null || host != null)
+            if (hostInterceptor == null)
             {
                 return host;
             }