Skip to content

Commit

Permalink
Add singleton example (protobuf-net#121)
Browse files Browse the repository at this point in the history
  • Loading branch information
Euan-McVie committed Nov 10, 2020
1 parent 27345e1 commit 61229be
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 7 deletions.
15 changes: 10 additions & 5 deletions examples/pb-net-grpc/Client_CS/Program.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
using Grpc.Core;
using System;
using System.Threading;
using System.Threading.Tasks;
using Grpc.Core;
using Grpc.Net.Client;
using MegaCorp;
using ProtoBuf.Grpc;
using ProtoBuf.Grpc.Client;
using Shared_CS;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace Client_CS
{
Expand All @@ -21,6 +21,7 @@ static async Task Main()
Console.WriteLine(result.Result); // 48

var clock = http.CreateGrpcService<ITimeService>();
var counter = http.CreateGrpcService<ICounter>();
using var cancel = new CancellationTokenSource(TimeSpan.FromMinutes(1));
var options = new CallOptions(cancellationToken: cancel.Token);

Expand All @@ -29,10 +30,14 @@ static async Task Main()
await foreach (var time in clock.SubscribeAsync(new CallContext(options)))
{
Console.WriteLine($"The time is now: {time.Time}");
var currentInc = await counter.IncrementAsync(new IncrementRequest { Inc = 1 });
Console.WriteLine($"Time recieved {currentInc.Result} times");
}
}
catch (RpcException) { }
catch (RpcException ex) { Console.WriteLine(ex); }
catch (OperationCanceledException) { }
Console.WriteLine("Press [Enter] to exit");
Console.ReadLine();
}
}
}
33 changes: 33 additions & 0 deletions examples/pb-net-grpc/Server_CS/FakeAuthenticationHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System.Security.Claims;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace Server_CS
{
class FakeAuthHandler : AuthenticationHandler<FakeAuthenticationSchemeOptions>
{
public const string SchemeName = "Fake";

public FakeAuthHandler(
IOptionsMonitor<FakeAuthenticationSchemeOptions> options,
ILoggerFactory logger,
UrlEncoder encoder,
ISystemClock clock)
: base(options, logger, encoder, clock)
{
}

protected override Task<AuthenticateResult> HandleAuthenticateAsync()
{
var claimsIdentity = new ClaimsIdentity(SchemeName);
var ticket = new AuthenticationTicket(new ClaimsPrincipal(claimsIdentity), Scheme.Name);
return Task.FromResult(AuthenticateResult.Success(ticket));
}
}

class FakeAuthenticationSchemeOptions : AuthenticationSchemeOptions
{ }
}
23 changes: 23 additions & 0 deletions examples/pb-net-grpc/Server_CS/MyCounter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Shared_CS;

namespace Server_CS
{
[Authorize]
public class MyCounter : ICounter
{
private int counter = 0;
private readonly object counterLock = new object();

ValueTask<IncrementResult> ICounter.IncrementAsync(IncrementRequest request)
{
lock (counterLock)
{
counter += request.Inc;
var result = new IncrementResult { Result = counter };
return new ValueTask<IncrementResult>(result);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
},
"Server_CS": {
"commandName": "Project",
"launchBrowser": true,
"launchBrowser": false,
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Microsoft.Extensions.DependencyInjection;
using ProtoBuf.Grpc.Configuration;

namespace Server_CS
{
internal class ServiceBinderWithServiceResolutionFromServiceCollection : ServiceBinder
{
private readonly IServiceCollection services;

public ServiceBinderWithServiceResolutionFromServiceCollection(IServiceCollection services)
{
this.services = services;
}

public override IList<object> GetMetadata(MethodInfo method, Type contractType, Type serviceType)
{
var resolvedServiceType = serviceType;
if (serviceType.IsInterface)
resolvedServiceType = services.SingleOrDefault(x => x.ServiceType == serviceType)?.ImplementationType ?? serviceType;

return base.GetMetadata(method, contractType, resolvedServiceType);
}
}
}
16 changes: 15 additions & 1 deletion examples/pb-net-grpc/Server_CS/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using ProtoBuf.Grpc.Server;
using Shared_CS;

namespace Server_CS
{
Expand All @@ -14,17 +15,30 @@ public void ConfigureServices(IServiceCollection services)
services.AddCodeFirstGrpc(config =>
{
config.ResponseCompressionLevel = System.IO.Compression.CompressionLevel.Optimal;
});
})
.WithBinderConfiguration(config => config.ServiceBinder = new ServiceBinderWithServiceResolutionFromServiceCollection(services));
services.AddCodeFirstGrpcReflection();

services.AddAuthentication(options =>
{
options.AddScheme<FakeAuthHandler>(FakeAuthHandler.SchemeName, FakeAuthHandler.SchemeName);
options.DefaultScheme = FakeAuthHandler.SchemeName;
});
services.AddAuthorization();
services.AddSingleton<ICounter, MyCounter>();
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment _)
{
app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
endpoints.MapGrpcService<ICounter>();
endpoints.MapGrpcService<MyCalculator>();
endpoints.MapGrpcService<MyTimeService>();
endpoints.MapCodeFirstGrpcReflectionService();
Expand Down
25 changes: 25 additions & 0 deletions examples/pb-net-grpc/Shared_CS/Counter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Threading.Tasks;
namespace Shared_CS
{
[ServiceContract]
public interface ICounter
{
ValueTask<IncrementResult> IncrementAsync(IncrementRequest request);
}

[DataContract]
public class IncrementRequest
{
[DataMember(Order = 1)]
public int Inc { get; set; }
}

[DataContract]
public class IncrementResult
{
[DataMember(Order = 1)]
public int Result { get; set; }
}
}

0 comments on commit 61229be

Please sign in to comment.