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