• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #region Copyright notice and license
2 
3 // Copyright 2015 gRPC authors.
4 //
5 // 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
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // 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.
16 
17 #endregion
18 
19 using System;
20 using System.Collections.Generic;
21 
22 namespace Grpc.Core
23 {
24     /// <summary>
25     /// Stores mapping of methods to server call handlers.
26     /// Normally, the <c>ServerServiceDefinition</c> objects will be created by the <c>BindService</c> factory method
27     /// that is part of the autogenerated code for a protocol buffers service definition.
28     /// </summary>
29     public class ServerServiceDefinition
30     {
31         readonly IReadOnlyList<Action<ServiceBinderBase>> addMethodActions;
32 
ServerServiceDefinition(List<Action<ServiceBinderBase>> addMethodActions)33         internal ServerServiceDefinition(List<Action<ServiceBinderBase>> addMethodActions)
34         {
35             this.addMethodActions = addMethodActions.AsReadOnly();
36         }
37 
38         /// <summary>
39         /// Forwards all the previously stored <c>AddMethod</c> calls to the service binder.
40         /// </summary>
BindService(ServiceBinderBase serviceBinder)41         internal void BindService(ServiceBinderBase serviceBinder)
42         {
43             foreach (var addMethodAction in addMethodActions)
44             {
45                 addMethodAction(serviceBinder);
46             }
47         }
48 
49         /// <summary>
50         /// Creates a new builder object for <c>ServerServiceDefinition</c>.
51         /// </summary>
52         /// <returns>The builder object.</returns>
CreateBuilder()53         public static Builder CreateBuilder()
54         {
55             return new Builder();
56         }
57 
58         /// <summary>
59         /// Builder class for <see cref="ServerServiceDefinition"/>.
60         /// </summary>
61         public class Builder
62         {
63             // to maintain legacy behavior, we need to detect duplicate keys and throw the same exception as before
64             readonly Dictionary<string, object> duplicateDetector = new Dictionary<string, object>();
65             // for each AddMethod call, we store an action that will later register the method and handler with ServiceBinderBase
66             readonly List<Action<ServiceBinderBase>> addMethodActions = new List<Action<ServiceBinderBase>>();
67 
68             /// <summary>
69             /// Creates a new instance of builder.
70             /// </summary>
Builder()71             public Builder()
72             {
73             }
74 
75             /// <summary>
76             /// Adds a definition for a single request - single response method.
77             /// </summary>
78             /// <typeparam name="TRequest">The request message class.</typeparam>
79             /// <typeparam name="TResponse">The response message class.</typeparam>
80             /// <param name="method">The method.</param>
81             /// <param name="handler">The method handler.</param>
82             /// <returns>This builder instance.</returns>
83             public Builder AddMethod<TRequest, TResponse>(
84                 Method<TRequest, TResponse> method,
85                 UnaryServerMethod<TRequest, TResponse> handler)
86                     where TRequest : class
87                     where TResponse : class
88             {
duplicateDetector.Add(method.FullName, null)89                 duplicateDetector.Add(method.FullName, null);
addMethodActions.Addnull90                 addMethodActions.Add((serviceBinder) => serviceBinder.AddMethod(method, handler));
91                 return this;
92             }
93 
94             /// <summary>
95             /// Adds a definition for a client streaming method.
96             /// </summary>
97             /// <typeparam name="TRequest">The request message class.</typeparam>
98             /// <typeparam name="TResponse">The response message class.</typeparam>
99             /// <param name="method">The method.</param>
100             /// <param name="handler">The method handler.</param>
101             /// <returns>This builder instance.</returns>
102             public Builder AddMethod<TRequest, TResponse>(
103                 Method<TRequest, TResponse> method,
104                 ClientStreamingServerMethod<TRequest, TResponse> handler)
105                     where TRequest : class
106                     where TResponse : class
107             {
duplicateDetector.Add(method.FullName, null)108                 duplicateDetector.Add(method.FullName, null);
addMethodActions.Addnull109                 addMethodActions.Add((serviceBinder) => serviceBinder.AddMethod(method, handler));
110                 return this;
111             }
112 
113             /// <summary>
114             /// Adds a definition for a server streaming method.
115             /// </summary>
116             /// <typeparam name="TRequest">The request message class.</typeparam>
117             /// <typeparam name="TResponse">The response message class.</typeparam>
118             /// <param name="method">The method.</param>
119             /// <param name="handler">The method handler.</param>
120             /// <returns>This builder instance.</returns>
121             public Builder AddMethod<TRequest, TResponse>(
122                 Method<TRequest, TResponse> method,
123                 ServerStreamingServerMethod<TRequest, TResponse> handler)
124                     where TRequest : class
125                     where TResponse : class
126             {
duplicateDetector.Add(method.FullName, null)127                 duplicateDetector.Add(method.FullName, null);
addMethodActions.Addnull128                 addMethodActions.Add((serviceBinder) => serviceBinder.AddMethod(method, handler));
129                 return this;
130             }
131 
132             /// <summary>
133             /// Adds a definition for a bidirectional streaming method.
134             /// </summary>
135             /// <typeparam name="TRequest">The request message class.</typeparam>
136             /// <typeparam name="TResponse">The response message class.</typeparam>
137             /// <param name="method">The method.</param>
138             /// <param name="handler">The method handler.</param>
139             /// <returns>This builder instance.</returns>
140             public Builder AddMethod<TRequest, TResponse>(
141                 Method<TRequest, TResponse> method,
142                 DuplexStreamingServerMethod<TRequest, TResponse> handler)
143                     where TRequest : class
144                     where TResponse : class
145             {
duplicateDetector.Add(method.FullName, null)146                 duplicateDetector.Add(method.FullName, null);
addMethodActions.Addnull147                 addMethodActions.Add((serviceBinder) => serviceBinder.AddMethod(method, handler));
148                 return this;
149             }
150 
151             /// <summary>
152             /// Creates an immutable <c>ServerServiceDefinition</c> from this builder.
153             /// </summary>
154             /// <returns>The <c>ServerServiceDefinition</c> object.</returns>
Build()155             public ServerServiceDefinition Build()
156             {
157                 return new ServerServiceDefinition(addMethodActions);
158             }
159         }
160     }
161 }
162