aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar apolcyn <apolcyn@google.com>2016-08-11 23:01:30 +0000
committerGravatar GitHub <noreply@github.com>2016-08-11 23:01:30 +0000
commitf2d8c608454d757976544c9e24ef3efdc224ec54 (patch)
tree63415c8f8bf890c2a1b1491cba92d2c1da0397e6
parentc05df4f309f05f29da4628f932b09de818fbefab (diff)
parent5312815ff212e6d4bbea1f1f6264b1295ca0106c (diff)
Merge pull request #7634 from apolcyn/use_dotnet_on_examples
add csharp hello world that uses dotnet cli
-rw-r--r--examples/csharp/helloworld-from-cli/Greeter/Helloworld.cs259
-rw-r--r--examples/csharp/helloworld-from-cli/Greeter/HelloworldGrpc.cs143
-rw-r--r--examples/csharp/helloworld-from-cli/Greeter/project.json22
-rw-r--r--examples/csharp/helloworld-from-cli/GreeterClient/Program.cs53
-rw-r--r--examples/csharp/helloworld-from-cli/GreeterClient/project.json26
-rw-r--r--examples/csharp/helloworld-from-cli/GreeterServer/Program.cs66
-rw-r--r--examples/csharp/helloworld-from-cli/GreeterServer/project.json26
-rw-r--r--examples/csharp/helloworld-from-cli/README.md59
8 files changed, 654 insertions, 0 deletions
diff --git a/examples/csharp/helloworld-from-cli/Greeter/Helloworld.cs b/examples/csharp/helloworld-from-cli/Greeter/Helloworld.cs
new file mode 100644
index 0000000000..6477b4f35b
--- /dev/null
+++ b/examples/csharp/helloworld-from-cli/Greeter/Helloworld.cs
@@ -0,0 +1,259 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: helloworld.proto
+#pragma warning disable 1591, 0612, 3021
+#region Designer generated code
+
+using pb = global::Google.Protobuf;
+using pbc = global::Google.Protobuf.Collections;
+using pbr = global::Google.Protobuf.Reflection;
+using scg = global::System.Collections.Generic;
+namespace Helloworld {
+
+ /// <summary>Holder for reflection information generated from helloworld.proto</summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public static partial class HelloworldReflection {
+
+ #region Descriptor
+ /// <summary>File descriptor for helloworld.proto</summary>
+ public static pbr::FileDescriptor Descriptor {
+ get { return descriptor; }
+ }
+ private static pbr::FileDescriptor descriptor;
+
+ static HelloworldReflection() {
+ byte[] descriptorData = global::System.Convert.FromBase64String(
+ string.Concat(
+ "ChBoZWxsb3dvcmxkLnByb3RvEgpoZWxsb3dvcmxkIhwKDEhlbGxvUmVxdWVz",
+ "dBIMCgRuYW1lGAEgASgJIh0KCkhlbGxvUmVwbHkSDwoHbWVzc2FnZRgBIAEo",
+ "CTJJCgdHcmVldGVyEj4KCFNheUhlbGxvEhguaGVsbG93b3JsZC5IZWxsb1Jl",
+ "cXVlc3QaFi5oZWxsb3dvcmxkLkhlbGxvUmVwbHkiAEI2Chtpby5ncnBjLmV4",
+ "YW1wbGVzLmhlbGxvd29ybGRCD0hlbGxvV29ybGRQcm90b1ABogIDSExXYgZw",
+ "cm90bzM="));
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+ new pbr::FileDescriptor[] { },
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Helloworld.HelloRequest), global::Helloworld.HelloRequest.Parser, new[]{ "Name" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Helloworld.HelloReply), global::Helloworld.HelloReply.Parser, new[]{ "Message" }, null, null, null)
+ }));
+ }
+ #endregion
+
+ }
+ #region Messages
+ /// <summary>
+ /// The request message containing the user's name.
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public sealed partial class HelloRequest : pb::IMessage<HelloRequest> {
+ private static readonly pb::MessageParser<HelloRequest> _parser = new pb::MessageParser<HelloRequest>(() => new HelloRequest());
+ public static pb::MessageParser<HelloRequest> Parser { get { return _parser; } }
+
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Helloworld.HelloworldReflection.Descriptor.MessageTypes[0]; }
+ }
+
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ public HelloRequest() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ public HelloRequest(HelloRequest other) : this() {
+ name_ = other.name_;
+ }
+
+ public HelloRequest Clone() {
+ return new HelloRequest(this);
+ }
+
+ /// <summary>Field number for the "name" field.</summary>
+ public const int NameFieldNumber = 1;
+ private string name_ = "";
+ public string Name {
+ get { return name_; }
+ set {
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ public override bool Equals(object other) {
+ return Equals(other as HelloRequest);
+ }
+
+ public bool Equals(HelloRequest other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if (Name != other.Name) return false;
+ return true;
+ }
+
+ public override int GetHashCode() {
+ int hash = 1;
+ if (Name.Length != 0) hash ^= Name.GetHashCode();
+ return hash;
+ }
+
+ public override string ToString() {
+ return pb::JsonFormatter.ToDiagnosticString(this);
+ }
+
+ public void WriteTo(pb::CodedOutputStream output) {
+ if (Name.Length != 0) {
+ output.WriteRawTag(10);
+ output.WriteString(Name);
+ }
+ }
+
+ public int CalculateSize() {
+ int size = 0;
+ if (Name.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
+ }
+ return size;
+ }
+
+ public void MergeFrom(HelloRequest other) {
+ if (other == null) {
+ return;
+ }
+ if (other.Name.Length != 0) {
+ Name = other.Name;
+ }
+ }
+
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ case 10: {
+ Name = input.ReadString();
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ /// <summary>
+ /// The response message containing the greetings
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public sealed partial class HelloReply : pb::IMessage<HelloReply> {
+ private static readonly pb::MessageParser<HelloReply> _parser = new pb::MessageParser<HelloReply>(() => new HelloReply());
+ public static pb::MessageParser<HelloReply> Parser { get { return _parser; } }
+
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Helloworld.HelloworldReflection.Descriptor.MessageTypes[1]; }
+ }
+
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ public HelloReply() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ public HelloReply(HelloReply other) : this() {
+ message_ = other.message_;
+ }
+
+ public HelloReply Clone() {
+ return new HelloReply(this);
+ }
+
+ /// <summary>Field number for the "message" field.</summary>
+ public const int MessageFieldNumber = 1;
+ private string message_ = "";
+ public string Message {
+ get { return message_; }
+ set {
+ message_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ public override bool Equals(object other) {
+ return Equals(other as HelloReply);
+ }
+
+ public bool Equals(HelloReply other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if (Message != other.Message) return false;
+ return true;
+ }
+
+ public override int GetHashCode() {
+ int hash = 1;
+ if (Message.Length != 0) hash ^= Message.GetHashCode();
+ return hash;
+ }
+
+ public override string ToString() {
+ return pb::JsonFormatter.ToDiagnosticString(this);
+ }
+
+ public void WriteTo(pb::CodedOutputStream output) {
+ if (Message.Length != 0) {
+ output.WriteRawTag(10);
+ output.WriteString(Message);
+ }
+ }
+
+ public int CalculateSize() {
+ int size = 0;
+ if (Message.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(Message);
+ }
+ return size;
+ }
+
+ public void MergeFrom(HelloReply other) {
+ if (other == null) {
+ return;
+ }
+ if (other.Message.Length != 0) {
+ Message = other.Message;
+ }
+ }
+
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ case 10: {
+ Message = input.ReadString();
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ #endregion
+
+}
+
+#endregion Designer generated code
diff --git a/examples/csharp/helloworld-from-cli/Greeter/HelloworldGrpc.cs b/examples/csharp/helloworld-from-cli/Greeter/HelloworldGrpc.cs
new file mode 100644
index 0000000000..041f5a78d7
--- /dev/null
+++ b/examples/csharp/helloworld-from-cli/Greeter/HelloworldGrpc.cs
@@ -0,0 +1,143 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: helloworld.proto
+// Original file comments:
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+#region Designer generated code
+
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using Grpc.Core;
+
+namespace Helloworld {
+ /// <summary>
+ /// The greeting service definition.
+ /// </summary>
+ public static class Greeter
+ {
+ static readonly string __ServiceName = "helloworld.Greeter";
+
+ static readonly Marshaller<global::Helloworld.HelloRequest> __Marshaller_HelloRequest = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloRequest.Parser.ParseFrom);
+ static readonly Marshaller<global::Helloworld.HelloReply> __Marshaller_HelloReply = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloReply.Parser.ParseFrom);
+
+ static readonly Method<global::Helloworld.HelloRequest, global::Helloworld.HelloReply> __Method_SayHello = new Method<global::Helloworld.HelloRequest, global::Helloworld.HelloReply>(
+ MethodType.Unary,
+ __ServiceName,
+ "SayHello",
+ __Marshaller_HelloRequest,
+ __Marshaller_HelloReply);
+
+ /// <summary>Service descriptor</summary>
+ public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
+ {
+ get { return global::Helloworld.HelloworldReflection.Descriptor.Services[0]; }
+ }
+
+ /// <summary>Base class for server-side implementations of Greeter</summary>
+ public abstract class GreeterBase
+ {
+ /// <summary>
+ /// Sends a greeting
+ /// </summary>
+ public virtual global::System.Threading.Tasks.Task<global::Helloworld.HelloReply> SayHello(global::Helloworld.HelloRequest request, ServerCallContext context)
+ {
+ throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+ }
+
+ }
+
+ /// <summary>Client for Greeter</summary>
+ public class GreeterClient : ClientBase<GreeterClient>
+ {
+ /// <summary>Creates a new client for Greeter</summary>
+ /// <param name="channel">The channel to use to make remote calls.</param>
+ public GreeterClient(Channel channel) : base(channel)
+ {
+ }
+ /// <summary>Creates a new client for Greeter that uses a custom <c>CallInvoker</c>.</summary>
+ /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
+ public GreeterClient(CallInvoker callInvoker) : base(callInvoker)
+ {
+ }
+ /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
+ protected GreeterClient() : base()
+ {
+ }
+ /// <summary>Protected constructor to allow creation of configured clients.</summary>
+ /// <param name="configuration">The client configuration.</param>
+ protected GreeterClient(ClientBaseConfiguration configuration) : base(configuration)
+ {
+ }
+
+ /// <summary>
+ /// Sends a greeting
+ /// </summary>
+ public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ {
+ return SayHello(request, new CallOptions(headers, deadline, cancellationToken));
+ }
+ /// <summary>
+ /// Sends a greeting
+ /// </summary>
+ public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, CallOptions options)
+ {
+ return CallInvoker.BlockingUnaryCall(__Method_SayHello, null, options, request);
+ }
+ /// <summary>
+ /// Sends a greeting
+ /// </summary>
+ public virtual AsyncUnaryCall<global::Helloworld.HelloReply> SayHelloAsync(global::Helloworld.HelloRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ {
+ return SayHelloAsync(request, new CallOptions(headers, deadline, cancellationToken));
+ }
+ /// <summary>
+ /// Sends a greeting
+ /// </summary>
+ public virtual AsyncUnaryCall<global::Helloworld.HelloReply> SayHelloAsync(global::Helloworld.HelloRequest request, CallOptions options)
+ {
+ return CallInvoker.AsyncUnaryCall(__Method_SayHello, null, options, request);
+ }
+ protected override GreeterClient NewInstance(ClientBaseConfiguration configuration)
+ {
+ return new GreeterClient(configuration);
+ }
+ }
+
+ /// <summary>Creates service definition that can be registered with a server</summary>
+ public static ServerServiceDefinition BindService(GreeterBase serviceImpl)
+ {
+ return ServerServiceDefinition.CreateBuilder()
+ .AddMethod(__Method_SayHello, serviceImpl.SayHello).Build();
+ }
+
+ }
+}
+#endregion
diff --git a/examples/csharp/helloworld-from-cli/Greeter/project.json b/examples/csharp/helloworld-from-cli/Greeter/project.json
new file mode 100644
index 0000000000..8774941810
--- /dev/null
+++ b/examples/csharp/helloworld-from-cli/Greeter/project.json
@@ -0,0 +1,22 @@
+{
+ "title": "Greeter",
+ "version": "1.0.0-*",
+ "buildOptions": {
+ "debugType": "portable",
+ },
+ "dependencies": {
+ "Google.Protobuf": "3.0.0-beta3",
+ "Grpc": "1.0.0-pre1",
+ },
+ "frameworks": {
+ "net45": {
+ "frameworkAssemblies": {
+ "System.Runtime": "",
+ "System.IO": ""
+ },
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1"
+ }
+ }
+ }
+}
diff --git a/examples/csharp/helloworld-from-cli/GreeterClient/Program.cs b/examples/csharp/helloworld-from-cli/GreeterClient/Program.cs
new file mode 100644
index 0000000000..444d473509
--- /dev/null
+++ b/examples/csharp/helloworld-from-cli/GreeterClient/Program.cs
@@ -0,0 +1,53 @@
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+using System;
+using Grpc.Core;
+using Helloworld;
+
+namespace GreeterClient
+{
+ class Program
+ {
+ public static void Main(string[] args)
+ {
+ Channel channel = new Channel("127.0.0.1:50051", ChannelCredentials.Insecure);
+
+ var client = new Greeter.GreeterClient(channel);
+ String user = "you";
+
+ var reply = client.SayHello(new HelloRequest { Name = user });
+ Console.WriteLine("Greeting: " + reply.Message);
+
+ channel.ShutdownAsync().Wait();
+ Console.WriteLine("Press any key to exit...");
+ Console.ReadKey();
+ }
+ }
+}
diff --git a/examples/csharp/helloworld-from-cli/GreeterClient/project.json b/examples/csharp/helloworld-from-cli/GreeterClient/project.json
new file mode 100644
index 0000000000..c2bf694cd8
--- /dev/null
+++ b/examples/csharp/helloworld-from-cli/GreeterClient/project.json
@@ -0,0 +1,26 @@
+{
+ "title": "GreeterClient",
+ "version": "1.0.0-*",
+ "buildOptions": {
+ "debugType": "portable",
+ "emitEntryPoint": "true"
+ },
+ "dependencies": {
+ "Google.Protobuf": "3.0.0-beta3",
+ "Grpc": "1.0.0-pre1",
+ "Greeter": {
+ "target": "project"
+ }
+ },
+ "frameworks": {
+ "net45": {
+ "frameworkAssemblies": {
+ "System.Runtime": "",
+ "System.IO": ""
+ },
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1"
+ }
+ }
+ }
+}
diff --git a/examples/csharp/helloworld-from-cli/GreeterServer/Program.cs b/examples/csharp/helloworld-from-cli/GreeterServer/Program.cs
new file mode 100644
index 0000000000..fdab379e81
--- /dev/null
+++ b/examples/csharp/helloworld-from-cli/GreeterServer/Program.cs
@@ -0,0 +1,66 @@
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+using System;
+using System.Threading.Tasks;
+using Grpc.Core;
+using Helloworld;
+
+namespace GreeterServer
+{
+ class GreeterImpl : Greeter.GreeterBase
+ {
+ // Server side handler of the SayHello RPC
+ public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
+ {
+ return Task.FromResult(new HelloReply { Message = "Hello " + request.Name });
+ }
+ }
+
+ class Program
+ {
+ const int Port = 50051;
+
+ public static void Main(string[] args)
+ {
+ Server server = new Server
+ {
+ Services = { Greeter.BindService(new GreeterImpl()) },
+ Ports = { new ServerPort("localhost", Port, ServerCredentials.Insecure) }
+ };
+ server.Start();
+
+ Console.WriteLine("Greeter server listening on port " + Port);
+ Console.WriteLine("Press any key to stop the server...");
+ Console.ReadKey();
+
+ server.ShutdownAsync().Wait();
+ }
+ }
+}
diff --git a/examples/csharp/helloworld-from-cli/GreeterServer/project.json b/examples/csharp/helloworld-from-cli/GreeterServer/project.json
new file mode 100644
index 0000000000..29a10670f4
--- /dev/null
+++ b/examples/csharp/helloworld-from-cli/GreeterServer/project.json
@@ -0,0 +1,26 @@
+{
+ "title": "GreeterServer",
+ "version": "1.0.0-*",
+ "buildOptions": {
+ "debugType": "portable",
+ "emitEntryPoint": "true"
+ },
+ "dependencies": {
+ "Google.Protobuf": "3.0.0-beta3",
+ "Grpc": "1.0.0-pre1",
+ "Greeter": {
+ "target": "project"
+ }
+ },
+ "frameworks": {
+ "net45": {
+ "frameworkAssemblies": {
+ "System.Runtime": "",
+ "System.IO": ""
+ },
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1"
+ }
+ }
+ }
+}
diff --git a/examples/csharp/helloworld-from-cli/README.md b/examples/csharp/helloworld-from-cli/README.md
new file mode 100644
index 0000000000..4db077631d
--- /dev/null
+++ b/examples/csharp/helloworld-from-cli/README.md
@@ -0,0 +1,59 @@
+gRPC in 3 minutes (C#)
+========================
+
+BACKGROUND
+-------------
+This is a different version of the helloworld example, using the dotnet sdk
+tools to build and run.
+
+For this sample, we've already generated the server and client stubs from [helloworld.proto][].
+
+Example projects in this directory depend on the [Grpc](https://www.nuget.org/packages/Grpc/)
+and [Google.Protobuf](https://www.nuget.org/packages/Google.Protobuf/) NuGet packages
+which have been already added to the project for you.
+
+The examples in this directory target .NET 4.5 framework, as .NET Core support is
+currently experimental.
+
+PREREQUISITES
+-------------
+
+- The DotNetCore SDK cli.
+
+- The .NET 4.5 framework.
+
+Both are available to download at https://www.microsoft.com/net/download
+
+BUILD
+-------
+
+From the `examples/csharp/helloworld-from-cli` directory:
+
+- `dotnet restore`
+
+- `dotnet build **/project.json` (this will automatically download NuGet dependencies)
+
+Try it!
+-------
+
+- Run the server
+
+ ```
+ > cd GreeterServer
+ > dotnet run
+ ```
+
+- Run the client
+
+ ```
+ > cd GreeterClient
+ > dotnet run
+ ```
+
+Tutorial
+--------
+
+You can find a more detailed tutorial about Grpc in [gRPC Basics: C#][]
+
+[helloworld.proto]:../../protos/helloworld.proto
+[gRPC Basics: C#]:http://www.grpc.io/docs/tutorials/basic/csharp.html