blob: 2d41b29fa0f41ba6e8c6438dd66db183655c94eb [file] [log] [blame]
Jan Tattermuschc0b37212015-03-13 08:35:41 -07001#region Copyright notice and license
2
Jan Tattermusch7897ae92017-06-07 22:57:36 +02003// Copyright 2015-2016 gRPC authors.
Jan Tattermuschc0b37212015-03-13 08:35:41 -07004//
Jan Tattermusch7897ae92017-06-07 22:57:36 +02005// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
Jan Tattermuschc0b37212015-03-13 08:35:41 -07008//
Jan Tattermusch7897ae92017-06-07 22:57:36 +02009// http://www.apache.org/licenses/LICENSE-2.0
Jan Tattermuschc0b37212015-03-13 08:35:41 -070010//
Jan Tattermusch7897ae92017-06-07 22:57:36 +020011// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
Jan Tattermuschc0b37212015-03-13 08:35:41 -070016
17#endregion
18
Jan Tattermusch054fae72016-03-23 07:54:50 -070019using Grpc.Core.Internal;
Jan Tattermuschd9495ab2016-03-22 15:01:57 -070020using Grpc.Core.Utils;
Jan Tattermuschc0b37212015-03-13 08:35:41 -070021
22namespace Grpc.Core
23{
Jan Tattermusch9e144142015-08-17 14:58:09 -070024 /// <summary>
Jan Tattermuschd9495ab2016-03-22 15:01:57 -070025 /// Generic base class for client-side stubs.
26 /// </summary>
27 public abstract class ClientBase<T> : ClientBase
Jan Tattermuschb2403582016-03-23 07:40:28 -070028 where T : ClientBase<T>
Jan Tattermuschd9495ab2016-03-22 15:01:57 -070029 {
30 /// <summary>
Jan Tattermuschb2403582016-03-23 07:40:28 -070031 /// Initializes a new instance of <c>ClientBase</c> class that
32 /// throws <c>NotImplementedException</c> upon invocation of any RPC.
33 /// This constructor is only provided to allow creation of test doubles
34 /// for client classes (e.g. mocking requires a parameterless constructor).
35 /// </summary>
36 protected ClientBase() : base()
37 {
38 }
39
40 /// <summary>
Jan Tattermuschd9495ab2016-03-22 15:01:57 -070041 /// Initializes a new instance of <c>ClientBase</c> class.
42 /// </summary>
Jan Tattermusch2f0a8372016-03-23 09:16:49 -070043 /// <param name="configuration">The configuration.</param>
44 protected ClientBase(ClientBaseConfiguration configuration) : base(configuration)
45 {
46 }
47
48 /// <summary>
49 /// Initializes a new instance of <c>ClientBase</c> class.
50 /// </summary>
Jan Tattermuschd9495ab2016-03-22 15:01:57 -070051 /// <param name="channel">The channel to use for remote call invocation.</param>
52 public ClientBase(Channel channel) : base(channel)
53 {
54 }
55
56 /// <summary>
57 /// Initializes a new instance of <c>ClientBase</c> class.
58 /// </summary>
59 /// <param name="callInvoker">The <c>CallInvoker</c> for remote call invocation.</param>
60 public ClientBase(CallInvoker callInvoker) : base(callInvoker)
61 {
62 }
63
64 /// <summary>
Jan Tattermuschc831a442016-03-22 17:23:55 -070065 /// Creates a new client that sets host field for calls explicitly.
66 /// gRPC supports multiple "hosts" being served by a single server.
67 /// By default (if a client was not created by calling this method),
68 /// host <c>null</c> with the meaning "use default host" is used.
69 /// </summary>
70 public T WithHost(string host)
71 {
Jan Tattermusch2f0a8372016-03-23 09:16:49 -070072 var newConfiguration = this.Configuration.WithHost(host);
73 return NewInstance(newConfiguration);
Jan Tattermuschc831a442016-03-22 17:23:55 -070074 }
75
76 /// <summary>
Jan Tattermusch2f0a8372016-03-23 09:16:49 -070077 /// Creates a new instance of client from given <c>ClientBaseConfiguration</c>.
Jan Tattermuschd9495ab2016-03-22 15:01:57 -070078 /// </summary>
Jan Tattermusch2f0a8372016-03-23 09:16:49 -070079 protected abstract T NewInstance(ClientBaseConfiguration configuration);
Jan Tattermuschd9495ab2016-03-22 15:01:57 -070080 }
81
82 /// <summary>
Jan Tattermusche5c9b802015-07-14 17:46:58 -070083 /// Base class for client-side stubs.
Jan Tattermuschc0b37212015-03-13 08:35:41 -070084 /// </summary>
Jan Tattermusche5c9b802015-07-14 17:46:58 -070085 public abstract class ClientBase
Jan Tattermuschc0b37212015-03-13 08:35:41 -070086 {
Jan Tattermusch2f0a8372016-03-23 09:16:49 -070087 readonly ClientBaseConfiguration configuration;
Jan Tattermuschd9495ab2016-03-22 15:01:57 -070088 readonly CallInvoker callInvoker;
Jan Tattermuschc0b37212015-03-13 08:35:41 -070089
Jan Tattermusch12855fc2015-08-24 16:43:23 -070090 /// <summary>
Jan Tattermuschb2403582016-03-23 07:40:28 -070091 /// Initializes a new instance of <c>ClientBase</c> class that
92 /// throws <c>NotImplementedException</c> upon invocation of any RPC.
93 /// This constructor is only provided to allow creation of test doubles
94 /// for client classes (e.g. mocking requires a parameterless constructor).
95 /// </summary>
96 protected ClientBase() : this(new UnimplementedCallInvoker())
97 {
98 }
99
100 /// <summary>
Jan Tattermusch12855fc2015-08-24 16:43:23 -0700101 /// Initializes a new instance of <c>ClientBase</c> class.
102 /// </summary>
Jan Tattermusch2f0a8372016-03-23 09:16:49 -0700103 /// <param name="configuration">The configuration.</param>
104 protected ClientBase(ClientBaseConfiguration configuration)
105 {
106 this.configuration = GrpcPreconditions.CheckNotNull(configuration, "configuration");
107 this.callInvoker = configuration.CreateDecoratedCallInvoker();
108 }
109
110 /// <summary>
111 /// Initializes a new instance of <c>ClientBase</c> class.
112 /// </summary>
Jan Tattermusch12855fc2015-08-24 16:43:23 -0700113 /// <param name="channel">The channel to use for remote call invocation.</param>
Jan Tattermuschd9495ab2016-03-22 15:01:57 -0700114 public ClientBase(Channel channel) : this(new DefaultCallInvoker(channel))
Jan Tattermuschc0b37212015-03-13 08:35:41 -0700115 {
Jan Tattermuschd9495ab2016-03-22 15:01:57 -0700116 }
117
118 /// <summary>
119 /// Initializes a new instance of <c>ClientBase</c> class.
120 /// </summary>
121 /// <param name="callInvoker">The <c>CallInvoker</c> for remote call invocation.</param>
Jan Tattermusch2f0a8372016-03-23 09:16:49 -0700122 public ClientBase(CallInvoker callInvoker) : this(new ClientBaseConfiguration(callInvoker, null))
Jan Tattermuschd9495ab2016-03-22 15:01:57 -0700123 {
Jan Tattermuschd9495ab2016-03-22 15:01:57 -0700124 }
125
126 /// <summary>
127 /// Gets the call invoker.
128 /// </summary>
129 protected CallInvoker CallInvoker
130 {
131 get { return this.callInvoker; }
Jan Tattermuschc0b37212015-03-13 08:35:41 -0700132 }
Jan Tattermusch2f0a8372016-03-23 09:16:49 -0700133
134 /// <summary>
135 /// Gets the configuration.
136 /// </summary>
137 internal ClientBaseConfiguration Configuration
138 {
139 get { return this.configuration; }
140 }
141
142 /// <summary>
143 /// Represents configuration of ClientBase. The class itself is visible to
144 /// subclasses, but contents are marked as internal to make the instances opaque.
145 /// The verbose name of this class was chosen to make name clash in generated code
146 /// less likely.
147 /// </summary>
148 protected internal class ClientBaseConfiguration
149 {
150 readonly CallInvoker undecoratedCallInvoker;
151 readonly string host;
152
153 internal ClientBaseConfiguration(CallInvoker undecoratedCallInvoker, string host)
154 {
155 this.undecoratedCallInvoker = GrpcPreconditions.CheckNotNull(undecoratedCallInvoker);
156 this.host = host;
157 }
158
159 internal CallInvoker CreateDecoratedCallInvoker()
160 {
161 return new InterceptingCallInvoker(undecoratedCallInvoker, hostInterceptor: (h) => host);
162 }
163
164 internal ClientBaseConfiguration WithHost(string host)
165 {
166 GrpcPreconditions.CheckNotNull(host, "host");
167 return new ClientBaseConfiguration(this.undecoratedCallInvoker, host);
168 }
169 }
Jan Tattermuschc0b37212015-03-13 08:35:41 -0700170 }
171}