aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Jan Tattermusch <jtattermusch@google.com>2016-03-23 09:16:49 -0700
committerGravatar Jan Tattermusch <jtattermusch@google.com>2016-04-01 16:25:45 -0700
commit2f0a837819a594db1397aff69f51323e948d2aba (patch)
treeed5343e2c023e3ab10b89f14aa4123096ad4f83b /src
parent054fae7e9d44414a1f27ea0dd6cbba237f735adf (diff)
introduce concept of opaque client base configuration
Diffstat (limited to 'src')
-rw-r--r--src/compiler/csharp_generator.cc13
-rw-r--r--src/csharp/Grpc.Core/ClientBase.cs71
-rw-r--r--src/csharp/Grpc.Core/Internal/InterceptingCallInvoker.cs4
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;
}