diff --git a/build/dependencies.props b/build/dependencies.props index 7eacdcaf2..70b486dc5 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -20,6 +20,7 @@ 3.12.0 3.16.1 0.6.0-beta.1 + 1.0.140 2.0.0-beta1.20214.1 0.3.0-alpha.20214.1 4.5.1 diff --git a/examples/Coder/Client/Client.csproj b/examples/Coder/Client/Client.csproj new file mode 100644 index 000000000..d8f0b5412 --- /dev/null +++ b/examples/Coder/Client/Client.csproj @@ -0,0 +1,13 @@ + + + + Exe + net5.0 + + + + + + + + diff --git a/examples/Coder/Client/Program.cs b/examples/Coder/Client/Program.cs new file mode 100644 index 000000000..ae0e2c577 --- /dev/null +++ b/examples/Coder/Client/Program.cs @@ -0,0 +1,42 @@ +#region Copyright notice and license + +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#endregion + +using System; +using System.Threading.Tasks; +using Grpc.Net.Client; +using ProtoBuf.Grpc.Client; +using Shared; + +namespace Client +{ + public class Program + { + static async Task Main(string[] args) + { + using var channel = GrpcChannel.ForAddress("https://localhost:5001"); + var client = channel.CreateGrpcService(); + + var reply = await client.SayHelloAsync(new HelloRequest { Name = "GreeterClient" }); + Console.WriteLine("Greeting: " + reply.Message); + + Console.WriteLine("Shutting down"); + Console.WriteLine("Press any key to exit..."); + Console.ReadKey(); + } + } +} diff --git a/examples/Coder/Coder.sln b/examples/Coder/Coder.sln new file mode 100644 index 000000000..7042bdb5c --- /dev/null +++ b/examples/Coder/Coder.sln @@ -0,0 +1,37 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29230.61 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Server", "Server\Server.csproj", "{534AC5F8-2DF2-40BD-87A5-B3D8310118C4}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Client", "Client\Client.csproj", "{48A1D3BC-A14B-436A-8822-6DE2BEF8B747}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shared", "Shared\Shared.csproj", "{9E978075-E00D-4FA9-9765-18CB51C5F5EE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {534AC5F8-2DF2-40BD-87A5-B3D8310118C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {534AC5F8-2DF2-40BD-87A5-B3D8310118C4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {534AC5F8-2DF2-40BD-87A5-B3D8310118C4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {534AC5F8-2DF2-40BD-87A5-B3D8310118C4}.Release|Any CPU.Build.0 = Release|Any CPU + {48A1D3BC-A14B-436A-8822-6DE2BEF8B747}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {48A1D3BC-A14B-436A-8822-6DE2BEF8B747}.Debug|Any CPU.Build.0 = Debug|Any CPU + {48A1D3BC-A14B-436A-8822-6DE2BEF8B747}.Release|Any CPU.ActiveCfg = Release|Any CPU + {48A1D3BC-A14B-436A-8822-6DE2BEF8B747}.Release|Any CPU.Build.0 = Release|Any CPU + {9E978075-E00D-4FA9-9765-18CB51C5F5EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9E978075-E00D-4FA9-9765-18CB51C5F5EE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9E978075-E00D-4FA9-9765-18CB51C5F5EE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9E978075-E00D-4FA9-9765-18CB51C5F5EE}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D22B3129-3BFB-41FA-9FCE-E45EBEF8C2DD} + EndGlobalSection +EndGlobal diff --git a/examples/Coder/Server/Program.cs b/examples/Coder/Server/Program.cs new file mode 100644 index 000000000..8ec497bbf --- /dev/null +++ b/examples/Coder/Server/Program.cs @@ -0,0 +1,38 @@ +#region Copyright notice and license + +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#endregion + +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Hosting; + +namespace Server +{ + public class Program + { + public static void Main(string[] args) + { + CreateHostBuilder(args).Build().Run(); + } + + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup(); + }); + } +} diff --git a/examples/Coder/Server/Properties/launchSettings.json b/examples/Coder/Server/Properties/launchSettings.json new file mode 100644 index 000000000..5e6a6188f --- /dev/null +++ b/examples/Coder/Server/Properties/launchSettings.json @@ -0,0 +1,12 @@ +{ + "profiles": { + "Server": { + "commandName": "Project", + "launchBrowser": false, + "applicationUrl": "https://localhost:5001", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/examples/Coder/Server/Server.csproj b/examples/Coder/Server/Server.csproj new file mode 100644 index 000000000..de392f3ab --- /dev/null +++ b/examples/Coder/Server/Server.csproj @@ -0,0 +1,13 @@ + + + + net5.0 + + + + + + + + + diff --git a/examples/Coder/Server/Services/GreeterService.cs b/examples/Coder/Server/Services/GreeterService.cs new file mode 100644 index 000000000..fe751cf3e --- /dev/null +++ b/examples/Coder/Server/Services/GreeterService.cs @@ -0,0 +1,41 @@ +#region Copyright notice and license + +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#endregion + +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using ProtoBuf.Grpc; +using Shared; + +namespace Server +{ + public class GreeterService : IGreeterService + { + private readonly ILogger _logger; + + public GreeterService(ILoggerFactory loggerFactory) + { + _logger = loggerFactory.CreateLogger(); + } + + public Task SayHelloAsync(HelloRequest request, CallContext context = default) + { + _logger.LogInformation($"Sending hello to {request.Name}"); + return Task.FromResult(new HelloReply { Message = "Hello " + request.Name }); + } + } +} diff --git a/examples/Coder/Server/Startup.cs b/examples/Coder/Server/Startup.cs new file mode 100644 index 000000000..a42542af2 --- /dev/null +++ b/examples/Coder/Server/Startup.cs @@ -0,0 +1,50 @@ +#region Copyright notice and license + +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#endregion + +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using ProtoBuf.Grpc.Server; + +namespace Server +{ + public class Startup + { + public void ConfigureServices(IServiceCollection services) + { + services.AddGrpc(); + services.AddCodeFirstGrpc(); + } + + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + + app.UseRouting(); + + app.UseEndpoints(endpoints => + { + endpoints.MapGrpcService(); + }); + } + } +} diff --git a/examples/Coder/Server/appsettings.Development.json b/examples/Coder/Server/appsettings.Development.json new file mode 100644 index 000000000..fe20c40cc --- /dev/null +++ b/examples/Coder/Server/appsettings.Development.json @@ -0,0 +1,10 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Grpc": "Information", + "Microsoft": "Information" + } + } +} diff --git a/examples/Coder/Server/appsettings.json b/examples/Coder/Server/appsettings.json new file mode 100644 index 000000000..f5f63744b --- /dev/null +++ b/examples/Coder/Server/appsettings.json @@ -0,0 +1,13 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information" + } + }, + "AllowedHosts": "*", + "Kestrel": { + "EndpointDefaults": { + "Protocols": "Http2" + } + } +} diff --git a/examples/Coder/Shared/HelloReply.cs b/examples/Coder/Shared/HelloReply.cs new file mode 100644 index 000000000..8736c0af5 --- /dev/null +++ b/examples/Coder/Shared/HelloReply.cs @@ -0,0 +1,29 @@ +#region Copyright notice and license + +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#endregion + +using System.Runtime.Serialization; + +namespace Shared +{ + [DataContract] + public class HelloReply + { + [DataMember(Order = 1)] + public string? Message { get; set; } + } +} diff --git a/examples/Coder/Shared/HelloRequest.cs b/examples/Coder/Shared/HelloRequest.cs new file mode 100644 index 000000000..393ad4853 --- /dev/null +++ b/examples/Coder/Shared/HelloRequest.cs @@ -0,0 +1,29 @@ +#region Copyright notice and license + +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#endregion + +using System.Runtime.Serialization; + +namespace Shared +{ + [DataContract] + public class HelloRequest + { + [DataMember(Order = 1)] + public string? Name { get; set; } + } +} diff --git a/examples/Coder/Shared/IGreeterService.cs b/examples/Coder/Shared/IGreeterService.cs new file mode 100644 index 000000000..a08039a92 --- /dev/null +++ b/examples/Coder/Shared/IGreeterService.cs @@ -0,0 +1,31 @@ +#region Copyright notice and license + +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#endregion + +using System.ServiceModel; +using System.Threading.Tasks; +using ProtoBuf.Grpc; + +namespace Shared +{ + [ServiceContract] + public interface IGreeterService + { + [OperationContract] + Task SayHelloAsync(HelloRequest request, CallContext context = default); + } +} diff --git a/examples/Coder/Shared/Shared.csproj b/examples/Coder/Shared/Shared.csproj new file mode 100644 index 000000000..4487c7911 --- /dev/null +++ b/examples/Coder/Shared/Shared.csproj @@ -0,0 +1,11 @@ + + + + net5.0 + + + + + + + diff --git a/examples/README.md b/examples/README.md index bb48c7428..4440bf9cc 100644 --- a/examples/README.md +++ b/examples/README.md @@ -246,3 +246,15 @@ To use gRPC with UDS: * Unix domain sockets * SocketsHttpHandler.ConnectCallback * [KestrelServerOptions.ListenUnixSocket](https://docs.microsoft.com/dotnet/api/microsoft.aspnetcore.server.kestrel.core.kestrelserveroptions.listenunixsocket) + +## [Coder](./Coder) + +The coder example shows how to create a code-first gRPC service and client. This example uses [protobuf-net.Grpc](https://github.com/protobuf-net/protobuf-net.Grpc), a community project that adds code-first support to `Grpc.AspNetCore` and `Grpc.Net.Client`. + +Code-first is a good choice if an app is written entirely in .NET. Code contracts can't be used by other languages and cross-platform apps should use *.proto* contracts. + +##### Scenarios: + +* Configure [protobuf-net.Grpc](https://github.com/protobuf-net/protobuf-net.Grpc) +* Create a code-first gRPC service +* Create a code-first gRPC client