Skip to content

Commit 3bd331e

Browse files
authored
client factories (#80)
1 parent 8a1f111 commit 3bd331e

File tree

7 files changed

+154
-7
lines changed

7 files changed

+154
-7
lines changed

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727

2828
<ExampleRefs>local</ExampleRefs> <!-- local or nuget-->
2929
<PBGRPCLibVersion>0.0.3-alpha.54</PBGRPCLibVersion>
30-
<GrpcDotNetVersion>2.28.0</GrpcDotNetVersion>
30+
<GrpcDotNetVersion>2.29.0-pre1</GrpcDotNetVersion>
3131
<GoogleProtobufVersion>3.12.0</GoogleProtobufVersion>
3232
<GrpcVersion>2.29.0</GrpcVersion>
3333
</PropertyGroup>

protobuf-net.Grpc.sln

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "protobuf-net.Grpc.Test.Inte
9797
EndProject
9898
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "toys", "toys", "{0DD003CC-90E1-4938-98F0-8181949CD727}"
9999
EndProject
100+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "protobuf-net.Grpc.ClientFactory", "src\protobuf-net.Grpc.ClientFactory\protobuf-net.Grpc.ClientFactory.csproj", "{4A7D8244-D6B2-4DD3-A0F3-1BF716FB1A0B}"
101+
EndProject
100102
Global
101103
GlobalSection(SolutionConfigurationPlatforms) = preSolution
102104
Debug|Any CPU = Debug|Any CPU
@@ -248,6 +250,12 @@ Global
248250
{7AF5B934-AEE9-4FD1-928D-AAE0F7098A32}.Release|Any CPU.Build.0 = Release|Any CPU
249251
{7AF5B934-AEE9-4FD1-928D-AAE0F7098A32}.VS|Any CPU.ActiveCfg = Debug|Any CPU
250252
{7AF5B934-AEE9-4FD1-928D-AAE0F7098A32}.VS|Any CPU.Build.0 = Debug|Any CPU
253+
{4A7D8244-D6B2-4DD3-A0F3-1BF716FB1A0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
254+
{4A7D8244-D6B2-4DD3-A0F3-1BF716FB1A0B}.Debug|Any CPU.Build.0 = Debug|Any CPU
255+
{4A7D8244-D6B2-4DD3-A0F3-1BF716FB1A0B}.Release|Any CPU.ActiveCfg = Release|Any CPU
256+
{4A7D8244-D6B2-4DD3-A0F3-1BF716FB1A0B}.Release|Any CPU.Build.0 = Release|Any CPU
257+
{4A7D8244-D6B2-4DD3-A0F3-1BF716FB1A0B}.VS|Any CPU.ActiveCfg = Debug|Any CPU
258+
{4A7D8244-D6B2-4DD3-A0F3-1BF716FB1A0B}.VS|Any CPU.Build.0 = Debug|Any CPU
251259
EndGlobalSection
252260
GlobalSection(SolutionProperties) = preSolution
253261
HideSolutionNode = FALSE
@@ -287,6 +295,7 @@ Global
287295
{6A3AC822-52E8-4AE2-8F71-385DF0D69891} = {F7FAC6AD-62B0-4B79-98AA-DBD99F84E4E9}
288296
{BCB98A08-8A05-41CA-B42F-9DBF3DB8D546} = {6A3AC822-52E8-4AE2-8F71-385DF0D69891}
289297
{7AF5B934-AEE9-4FD1-928D-AAE0F7098A32} = {0A84599D-2CE9-416E-888F-24652EEAB0B3}
298+
{4A7D8244-D6B2-4DD3-A0F3-1BF716FB1A0B} = {39491A90-84A2-4E13-B867-CFC3D4592084}
290299
EndGlobalSection
291300
GlobalSection(ExtensibilityGlobals) = postSolution
292301
SolutionGuid = {BA14B07C-CA29-430D-A600-F37A050636D3}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using Grpc.Net.ClientFactory;
2+
using Microsoft.Extensions.DependencyInjection;
3+
using ProtoBuf.Grpc.Client;
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Text;
7+
8+
namespace ProtoBuf.Grpc.ClientFactory
9+
{
10+
/// <summary>
11+
/// Provides extension methods to the IServiceCollection API
12+
/// </summary>
13+
public static class ServicesExtensions
14+
{
15+
/// <summary>
16+
/// Registers a provider that can recognize and handle code-first services
17+
/// </summary>
18+
public static IHttpClientBuilder AddCodeFirstGrpcClient<T>(this IServiceCollection services) where T : class
19+
=> services.AddGrpcClient<T>().ConfigureCodeFirstGrpcClient<T>();
20+
21+
/// <summary>
22+
/// Registers a provider that can recognize and handle code-first services
23+
/// </summary>
24+
public static IHttpClientBuilder AddCodeFirstGrpcClient<T>(this IServiceCollection services,
25+
string name) where T : class
26+
=> services.AddGrpcClient<T>(name).ConfigureCodeFirstGrpcClient<T>();
27+
28+
/// <summary>
29+
/// Registers a provider that can recognize and handle code-first services
30+
/// </summary>
31+
public static IHttpClientBuilder AddCodeFirstGrpcClient<T>(this IServiceCollection services,
32+
Action<GrpcClientFactoryOptions> configureClient) where T : class
33+
=> services.AddGrpcClient<T>(configureClient).ConfigureCodeFirstGrpcClient<T>();
34+
35+
/// <summary>
36+
/// Configures the provided client-builder to use code-first GRPC for client creation
37+
/// </summary>
38+
public static IHttpClientBuilder ConfigureCodeFirstGrpcClient<T>(this IHttpClientBuilder clientBuilder) where T : class
39+
=> clientBuilder.ConfigureGrpcClientCreator(
40+
(services, callInvoker) => Client.GrpcClientFactory.CreateGrpcService<T>(callInvoker,
41+
services.GetService<Configuration.ClientFactory>()));
42+
}
43+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netstandard2.1</TargetFramework>
5+
<RootNamespace>ProtoBuf.Grpc.ClientFactory</RootNamespace>
6+
<LangVersion>preview</LangVersion>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<PackageReference Include="Grpc.Net.ClientFactory" Version="$(GrpcDotNetVersion)" />
11+
<ProjectReference Include="..\protobuf-net.Grpc\protobuf-net.Grpc.csproj" />
12+
</ItemGroup>
13+
14+
</Project>

src/protobuf-net.Grpc/Client/GrpcClientFactory.cs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,28 @@ public static bool AllowUnencryptedHttp2
2626
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2727
public static TService CreateGrpcService<TService>(this ChannelBase client, ClientFactory? clientFactory = null)
2828
where TService : class
29-
=> (clientFactory ?? ClientFactory.Default).CreateClient<TService>(client.CreateCallInvoker());
29+
=> CreateGrpcService<TService>(client.CreateCallInvoker(), clientFactory);
30+
31+
/// <summary>
32+
/// Creates a code-first service backed by a ChannelBase instance
33+
/// </summary>
34+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
35+
public static TService CreateGrpcService<TService>(CallInvoker client, ClientFactory? clientFactory = null)
36+
where TService : class
37+
=> (clientFactory ?? ClientFactory.Default).CreateClient<TService>(client);
3038

3139
/// <summary>
3240
/// Creates a general purpose service backed by a ChannelBase instance
3341
/// </summary>
3442
[MethodImpl(MethodImplOptions.AggressiveInlining)]
3543
public static GrpcClient CreateGrpcService(this ChannelBase client, Type serviceType, ClientFactory? clientFactory = null)
36-
=> (clientFactory ?? ClientFactory.Default).CreateClient(client.CreateCallInvoker(), serviceType);
44+
=> CreateGrpcService(client.CreateCallInvoker(), serviceType, clientFactory);
45+
46+
/// <summary>
47+
/// Creates a general purpose service backed by a ChannelBase instance
48+
/// </summary>
49+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
50+
public static GrpcClient CreateGrpcService(CallInvoker client, Type serviceType, ClientFactory? clientFactory = null)
51+
=> (clientFactory ?? ClientFactory.Default).CreateClient(client, serviceType);
3752
}
3853
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#if CLIENT_FACTORY
2+
3+
using Grpc.Net.ClientFactory;
4+
using Microsoft.Extensions.DependencyInjection;
5+
using ProtoBuf.Grpc.ClientFactory;
6+
using System;
7+
using System.Runtime.Serialization;
8+
using System.ServiceModel;
9+
using System.Threading.Tasks;
10+
using Xunit;
11+
namespace protobuf_net.Grpc.Test
12+
{
13+
public class ClientFactoryTests
14+
{
15+
[Fact]
16+
public void CanConfigureCodeFirstClient()
17+
{
18+
var services = new ServiceCollection();
19+
services.AddCodeFirstGrpcClient<IMyService>(o =>
20+
{
21+
o.Address = new Uri("http://localhost");
22+
});
23+
var serviceProvider = services.BuildServiceProvider();
24+
25+
var clientFactory = serviceProvider.GetRequiredService<GrpcClientFactory>();
26+
var client = clientFactory.CreateClient<IMyService>(nameof(IMyService));
27+
28+
Assert.NotNull(client);
29+
var name = client.GetType().FullName;
30+
Assert.StartsWith("ProtoBuf.Grpc.Internal.Proxies.ClientBase.", name);
31+
}
32+
33+
[Fact]
34+
public void CanConfigureHttpClientBuilder()
35+
{
36+
var services = new ServiceCollection();
37+
services.AddGrpcClient<IMyService>(o =>
38+
{
39+
o.Address = new Uri("http://localhost");
40+
}).ConfigureCodeFirstGrpcClient<IMyService>();
41+
var serviceProvider = services.BuildServiceProvider();
42+
43+
var clientFactory = serviceProvider.GetRequiredService<GrpcClientFactory>();
44+
var client = clientFactory.CreateClient<IMyService>(nameof(IMyService));
45+
46+
Assert.NotNull(client);
47+
var name = client.GetType().FullName;
48+
Assert.StartsWith("ProtoBuf.Grpc.Internal.Proxies.ClientBase.", name);
49+
}
50+
}
51+
52+
[ServiceContract]
53+
public interface IMyService
54+
{
55+
[OperationContract]
56+
public ValueTask<Dummy> UnaryCall(Dummy value);
57+
}
58+
59+
[DataContract]
60+
public class Dummy { }
61+
}
62+
#endif

tests/protobuf-net.Grpc.Test/protobuf-net.Grpc.Test.csproj

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,23 @@
77
<IsPackable>false</IsPackable>
88
<LangVersion>preview</LangVersion>
99
</PropertyGroup>
10-
10+
<PropertyGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
11+
<DefineConstants>$(DefineConstants);CLIENT_FACTORY</DefineConstants>
12+
</PropertyGroup>
13+
1114
<ItemGroup>
1215
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" />
1316
<PackageReference Include="xunit" Version="2.4.1" />
1417
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
1518
<PrivateAssets>all</PrivateAssets>
1619
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1720
</PackageReference>
21+
<ProjectReference Include="..\..\src\protobuf-net.Grpc\protobuf-net.Grpc.csproj" />
1822
</ItemGroup>
1923

20-
<ItemGroup>
21-
<!--<ProjectReference Include="..\..\src\protobuf-net.Grpc.AspNetCore\protobuf-net.Grpc.AspNetCore.csproj" />-->
22-
<ProjectReference Include="..\..\src\protobuf-net.Grpc\protobuf-net.Grpc.csproj" />
24+
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
25+
<ProjectReference Include="..\..\src\protobuf-net.Grpc.ClientFactory\protobuf-net.Grpc.ClientFactory.csproj" />
26+
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.4" />
2327
</ItemGroup>
2428

2529
</Project>

0 commit comments

Comments
 (0)