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 using System.Collections.ObjectModel;
22 using System.Linq;
23 using Grpc.Core.Interceptors;
24 using Grpc.Core.Internal;
25 using Grpc.Core.Utils;
26 
27 namespace Grpc.Core
28 {
29     /// <summary>
30     /// Mapping of method names to server call handlers.
31     /// Normally, the <c>ServerServiceDefinition</c> objects will be created by the <c>BindService</c> factory method
32     /// that is part of the autogenerated code for a protocol buffers service definition.
33     /// </summary>
34     public class ServerServiceDefinition
35     {
36         readonly ReadOnlyDictionary<string, IServerCallHandler> callHandlers;
37 
ServerServiceDefinition(Dictionary<string, IServerCallHandler> callHandlers)38         internal ServerServiceDefinition(Dictionary<string, IServerCallHandler> callHandlers)
39         {
40             this.callHandlers = new ReadOnlyDictionary<string, IServerCallHandler>(callHandlers);
41         }
42 
43         internal IDictionary<string, IServerCallHandler> CallHandlers
44         {
45             get
46             {
47                 return this.callHandlers;
48             }
49         }
50 
51         /// <summary>
52         /// Creates a new builder object for <c>ServerServiceDefinition</c>.
53         /// </summary>
54         /// <returns>The builder object.</returns>
CreateBuilder()55         public static Builder CreateBuilder()
56         {
57             return new Builder();
58         }
59 
60         /// <summary>
61         /// Builder class for <see cref="ServerServiceDefinition"/>.
62         /// </summary>
63         public class Builder
64         {
65             readonly Dictionary<string, IServerCallHandler> callHandlers = new Dictionary<string, IServerCallHandler>();
66 
67             /// <summary>
68             /// Creates a new instance of builder.
69             /// </summary>
Builder()70             public Builder()
71             {
72             }
73 
74             /// <summary>
75             /// Adds a definitions for a single request - single response method.
76             /// </summary>
77             /// <typeparam name="TRequest">The request message class.</typeparam>
78             /// <typeparam name="TResponse">The response message class.</typeparam>
79             /// <param name="method">The method.</param>
80             /// <param name="handler">The method handler.</param>
81             /// <returns>This builder instance.</returns>
82             public Builder AddMethod<TRequest, TResponse>(
83                 Method<TRequest, TResponse> method,
84                 UnaryServerMethod<TRequest, TResponse> handler)
85                     where TRequest : class
86                     where TResponse : class
87             {
callHandlers.Add(method.FullName, ServerCalls.UnaryCall(method, handler))88                 callHandlers.Add(method.FullName, ServerCalls.UnaryCall(method, handler));
89                 return this;
90             }
91 
92             /// <summary>
93             /// Adds a definitions for a client streaming method.
94             /// </summary>
95             /// <typeparam name="TRequest">The request message class.</typeparam>
96             /// <typeparam name="TResponse">The response message class.</typeparam>
97             /// <param name="method">The method.</param>
98             /// <param name="handler">The method handler.</param>
99             /// <returns>This builder instance.</returns>
100             public Builder AddMethod<TRequest, TResponse>(
101                 Method<TRequest, TResponse> method,
102                 ClientStreamingServerMethod<TRequest, TResponse> handler)
103                     where TRequest : class
104                     where TResponse : class
105             {
callHandlers.Add(method.FullName, ServerCalls.ClientStreamingCall(method, handler))106                 callHandlers.Add(method.FullName, ServerCalls.ClientStreamingCall(method, handler));
107                 return this;
108             }
109 
110             /// <summary>
111             /// Adds a definitions for a server streaming method.
112             /// </summary>
113             /// <typeparam name="TRequest">The request message class.</typeparam>
114             /// <typeparam name="TResponse">The response message class.</typeparam>
115             /// <param name="method">The method.</param>
116             /// <param name="handler">The method handler.</param>
117             /// <returns>This builder instance.</returns>
118             public Builder AddMethod<TRequest, TResponse>(
119                 Method<TRequest, TResponse> method,
120                 ServerStreamingServerMethod<TRequest, TResponse> handler)
121                     where TRequest : class
122                     where TResponse : class
123             {
callHandlers.Add(method.FullName, ServerCalls.ServerStreamingCall(method, handler))124                 callHandlers.Add(method.FullName, ServerCalls.ServerStreamingCall(method, handler));
125                 return this;
126             }
127 
128             /// <summary>
129             /// Adds a definitions for a bidirectional streaming method.
130             /// </summary>
131             /// <typeparam name="TRequest">The request message class.</typeparam>
132             /// <typeparam name="TResponse">The response message class.</typeparam>
133             /// <param name="method">The method.</param>
134             /// <param name="handler">The method handler.</param>
135             /// <returns>This builder instance.</returns>
136             public Builder AddMethod<TRequest, TResponse>(
137                 Method<TRequest, TResponse> method,
138                 DuplexStreamingServerMethod<TRequest, TResponse> handler)
139                     where TRequest : class
140                     where TResponse : class
141             {
callHandlers.Add(method.FullName, ServerCalls.DuplexStreamingCall(method, handler))142                 callHandlers.Add(method.FullName, ServerCalls.DuplexStreamingCall(method, handler));
143                 return this;
144             }
145 
146             /// <summary>
147             /// Creates an immutable <c>ServerServiceDefinition</c> from this builder.
148             /// </summary>
149             /// <returns>The <c>ServerServiceDefinition</c> object.</returns>
Build()150             public ServerServiceDefinition Build()
151             {
152                 return new ServerServiceDefinition(callHandlers);
153             }
154         }
155     }
156 }
157