diff options
author | Jan Tattermusch <jtattermusch@google.com> | 2016-03-23 09:16:49 -0700 |
---|---|---|
committer | Jan Tattermusch <jtattermusch@google.com> | 2016-04-01 16:25:45 -0700 |
commit | 2f0a837819a594db1397aff69f51323e948d2aba (patch) | |
tree | ed5343e2c023e3ab10b89f14aa4123096ad4f83b /src | |
parent | 054fae7e9d44414a1f27ea0dd6cbba237f735adf (diff) |
introduce concept of opaque client base configuration
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/csharp_generator.cc | 13 | ||||
-rw-r--r-- | src/csharp/Grpc.Core/ClientBase.cs | 71 | ||||
-rw-r--r-- | src/csharp/Grpc.Core/Internal/InterceptingCallInvoker.cs | 4 |
3 files changed, 72 insertions, 16 deletions
diff --git a/src/compiler/csharp_generator.cc b/src/compiler/csharp_generator.cc index 1343233423..a83290af12 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 b21d01c5e2..e2e47893cc 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; @@ -58,6 +55,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> /// <param name="channel">The channel to use for remote call invocation.</param> public ClientBase(Channel channel) : base(channel) { @@ -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> @@ -110,6 +115,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> /// <param name="channel">The channel to use for remote call invocation.</param> public ClientBase(Channel channel) : this(new DefaultCallInvoker(channel)) { @@ -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 1b8c54a6da..53569760ac 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; } |