Skip to content

Commit 2008641

Browse files
authored
Merge pull request #28 from jacqueskang/specify-endpoint-contract
support specifying contract for each endpoint
2 parents 6387a4f + a9fbdf8 commit 2008641

File tree

16 files changed

+129
-97
lines changed

16 files changed

+129
-97
lines changed

README.md

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
# IpcServiceFramework
44

5-
A .NET Core lightweight inter-process communication framework allowing invoking a service via named pipeline (in a similar way as WCF, which is currently unavailable for .NET Core).
5+
A .NET Core lightweight inter-process communication framework allowing invoking a service via named pipeline and/or TCP (in a similar way as WCF, which is currently unavailable for .NET Core).
66

77
Support using primitive or complexe types in service contract.
88

9-
Support multi-threading on server side with configurable number of threads.
9+
Support multi-threading on server side with configurable number of threads (named pipeline endpoint only).
1010

1111
[ASP.NET Core Dependency Injection framework](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection) friendly.
1212

@@ -48,25 +48,28 @@ IpcServiceFramework is available via NuGet:
4848
### Step 3 - Host the service in Console application
4949

5050
```csharp
51-
class Program
51+
class Program
5252
{
5353
static void Main(string[] args)
5454
{
5555
// configure DI
5656
IServiceCollection services = ConfigureServices(new ServiceCollection());
5757

58-
// run IPC service host
59-
IpcServiceHostBuilder
60-
.Buid("pipeName", services.BuildServiceProvider())
58+
// build and run service host
59+
new IpcServiceHostBuilder(services.BuildServiceProvider())
60+
.AddNamedPipeEndpoint<IComputingService>(name: "endpoint1", pipeName: "pipeName")
61+
.AddTcpEndpoint<IComputingService>(name: "endpoint2", ipEndpoint: IPAddress.Loopback, port: 45684)
62+
.Build()
6163
.Run();
6264
}
6365

6466
private static IServiceCollection ConfigureServices(IServiceCollection services)
6567
{
6668
return services
67-
.AddIpc(options =>
69+
.AddIpc()
70+
.AddNamedPipe(options =>
6871
{
69-
options.ThreadCount = 4;
72+
options.ThreadCount = 2;
7073
})
7174
.AddService<IComputingService, ComputingService>();
7275
}
@@ -77,8 +80,11 @@ It's possible to host IPC service in web application, please check out the sampl
7780
### Step 4 - Invoke the service from client process
7881

7982
```csharp
80-
var proxy = new IpcServiceClient<IComputingService>("pipeName");
81-
float result = await proxy.InvokeAsync(x => x.AddFloat(1.23f, 4.56f));
83+
IpcServiceClient<IComputingService> client = new IpcServiceClientBuilder<IComputingService>()
84+
.UseNamedPipe("pipeName") // or .UseTcp(IPAddress.Loopback, 45684) to invoke using TCP
85+
.Build();
86+
87+
float result = await client.InvokeAsync(x => x.AddFloat(1.23f, 4.56f));
8288
```
8389

8490
__Please feel free to download, fork and/or provide any feedback!__

src/IpcServiceSample.ConsoleClient/Program.cs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,26 @@ private static async Task MainAsync(string[] args)
1818
{
1919
try
2020
{
21-
IpcServiceClient<IComputingService> client = new IpcServiceClientBuilder<IComputingService>()
22-
// Comment in if you wish to use TCP instead
21+
IpcServiceClient<IComputingService> computingClient = new IpcServiceClientBuilder<IComputingService>()
2322
.UseNamedPipe("pipeName")
24-
// Comment out if you wish to use TCP instead
25-
// .UseTcp(IPAddress.Loopback, 45684)
23+
.Build();
24+
25+
IpcServiceClient<ISystemService> systemClient = new IpcServiceClientBuilder<ISystemService>()
26+
.UseTcp(IPAddress.Loopback, 45684)
2627
.Build();
2728

2829
// test 1: call IPC service method with primitive types
29-
float result1 = await client.InvokeAsync(x => x.AddFloat(1.23f, 4.56f));
30+
float result1 = await computingClient.InvokeAsync(x => x.AddFloat(1.23f, 4.56f));
3031
Console.WriteLine($"[TEST 1] sum of 2 floating number is: {result1}");
3132

3233
// test 2: call IPC service method with complex types
33-
ComplexNumber result2 = await client.InvokeAsync(x => x.AddComplexNumber(
34+
ComplexNumber result2 = await computingClient.InvokeAsync(x => x.AddComplexNumber(
3435
new ComplexNumber(0.1f, 0.3f),
3536
new ComplexNumber(0.2f, 0.6f)));
3637
Console.WriteLine($"[TEST 2] sum of 2 complexe number is: {result2.A}+{result2.B}i");
3738

3839
// test 3: call IPC service method with an array of complex types
39-
ComplexNumber result3 = await client.InvokeAsync(x => x.AddComplexNumbers(new[]
40+
ComplexNumber result3 = await computingClient.InvokeAsync(x => x.AddComplexNumbers(new[]
4041
{
4142
new ComplexNumber(0.5f, 0.4f),
4243
new ComplexNumber(0.2f, 0.1f),
@@ -45,20 +46,20 @@ private static async Task MainAsync(string[] args)
4546
Console.WriteLine($"[TEST 3] sum of 3 complexe number is: {result3.A}+{result3.B}i");
4647

4748
// test 4: call IPC service method without parameter or return
48-
await client.InvokeAsync(x => x.DoNothing());
49+
await systemClient.InvokeAsync(x => x.DoNothing());
4950
Console.WriteLine($"[TEST 4] invoked DoNothing()");
5051

5152
// test 5: call IPC service method with enum parameter
52-
string text = await client.InvokeAsync(x => x.ConvertText("hEllO woRd!", TextStyle.Upper));
53+
string text = await systemClient.InvokeAsync(x => x.ConvertText("hEllO woRd!", TextStyle.Upper));
5354
Console.WriteLine($"[TEST 5] {text}");
5455

5556
// test 6: call IPC service method returning GUID
56-
Guid generatedId = await client.InvokeAsync(x => x.GenerateId());
57+
Guid generatedId = await systemClient.InvokeAsync(x => x.GenerateId());
5758
Console.WriteLine($"[TEST 6] generated ID is: {generatedId}");
5859

5960
// test 7: call IPC service method with byte array
6061
byte[] input = Encoding.UTF8.GetBytes("Test");
61-
byte[] reversed = await client.InvokeAsync(x => x.ReverseBytes(input));
62+
byte[] reversed = await systemClient.InvokeAsync(x => x.ReverseBytes(input));
6263
Console.WriteLine($"[TEST 7] reversed bytes are: {Convert.ToBase64String(reversed)}");
6364

6465
}
Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Globalization;
4-
using System.Linq;
5-
using IpcServiceSample.ServiceContracts;
1+
using IpcServiceSample.ServiceContracts;
62
using Microsoft.Extensions.Logging;
3+
using System.Collections.Generic;
74

85
namespace IpcServiceSample.ConsoleServer
96
{
@@ -26,7 +23,7 @@ public ComplexNumber AddComplexNumbers(IEnumerable<ComplexNumber> numbers)
2623
{
2724
_logger.LogInformation($"{nameof(AddComplexNumbers)} called.");
2825
var result = new ComplexNumber(0, 0);
29-
foreach (var number in numbers)
26+
foreach (ComplexNumber number in numbers)
3027
{
3128
result = new ComplexNumber(result.A + number.A, result.B + number.B);
3229
}
@@ -38,31 +35,5 @@ public float AddFloat(float x, float y)
3835
_logger.LogInformation($"{nameof(AddFloat)} called.");
3936
return x + y;
4037
}
41-
42-
public string ConvertText(string text, TextStyle style)
43-
{
44-
switch (style)
45-
{
46-
case TextStyle.TitleCase:
47-
return CultureInfo.InvariantCulture.TextInfo.ToTitleCase(text);
48-
case TextStyle.Upper:
49-
return CultureInfo.InvariantCulture.TextInfo.ToUpper(text);
50-
default:
51-
return text;
52-
}
53-
}
54-
55-
public void DoNothing()
56-
{ }
57-
58-
public Guid GenerateId()
59-
{
60-
return Guid.NewGuid();
61-
}
62-
63-
public byte[] ReverseBytes(byte[] input)
64-
{
65-
return input.Reverse().ToArray();
66-
}
6738
}
6839
}

src/IpcServiceSample.ConsoleServer/Program.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,22 @@
1-
using System.Net;
2-
using IpcServiceSample.ServiceContracts;
1+
using IpcServiceSample.ServiceContracts;
32
using JKang.IpcServiceFramework;
43
using Microsoft.Extensions.DependencyInjection;
54
using Microsoft.Extensions.Logging;
5+
using System.Net;
66

77
namespace IpcServiceSample.ConsoleServer
88
{
99
class Program
1010
{
1111
static void Main(string[] args)
1212
{
13-
// build service provider
13+
// configure DI
1414
IServiceCollection services = ConfigureServices(new ServiceCollection());
15-
ServiceProvider serviceProvider = services.BuildServiceProvider();
1615

17-
// TODO start IPC service host
18-
new IpcServiceHostBuilder(serviceProvider)
19-
.AddNamedPipeEndpoint("endpoint1", "pipeName")
20-
.AddTcpEndpoint("endpoint2", IPAddress.Loopback, 45684)
16+
// build and run service host
17+
new IpcServiceHostBuilder(services.BuildServiceProvider())
18+
.AddNamedPipeEndpoint<IComputingService>("computingEndpoint", "pipeName")
19+
.AddTcpEndpoint<ISystemService>("systemEndpoint", IPAddress.Loopback, 45684)
2120
.Build()
2221
.Run();
2322
}
@@ -37,7 +36,8 @@ private static IServiceCollection ConfigureServices(IServiceCollection services)
3736
{
3837
options.ThreadCount = 2;
3938
})
40-
.AddService<IComputingService, ComputingService>();
39+
.AddService<IComputingService, ComputingService>()
40+
.AddService<ISystemService, SystemService>();
4141

4242
return services;
4343
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using IpcServiceSample.ServiceContracts;
2+
using System;
3+
using System.Globalization;
4+
using System.Linq;
5+
6+
namespace IpcServiceSample.ConsoleServer
7+
{
8+
public class SystemService : ISystemService
9+
{
10+
public string ConvertText(string text, TextStyle style)
11+
{
12+
switch (style)
13+
{
14+
case TextStyle.TitleCase:
15+
return CultureInfo.InvariantCulture.TextInfo.ToTitleCase(text);
16+
case TextStyle.Upper:
17+
return CultureInfo.InvariantCulture.TextInfo.ToUpper(text);
18+
default:
19+
return text;
20+
}
21+
}
22+
23+
public void DoNothing()
24+
{ }
25+
26+
public Guid GenerateId()
27+
{
28+
return Guid.NewGuid();
29+
}
30+
31+
public byte[] ReverseBytes(byte[] input)
32+
{
33+
return input.Reverse().ToArray();
34+
}
35+
}
36+
}

src/IpcServiceSample.ServiceContracts/IComputingService.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,6 @@ public interface IComputingService
88
float AddFloat(float x, float y);
99
ComplexNumber AddComplexNumber(ComplexNumber x, ComplexNumber y);
1010
ComplexNumber AddComplexNumbers(IEnumerable<ComplexNumber> numbers);
11-
void DoNothing();
12-
string ConvertText(string text, TextStyle style);
13-
Guid GenerateId();
14-
byte[] ReverseBytes(byte[] input);
1511
}
1612

1713
public class ComplexNumber
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace IpcServiceSample.ServiceContracts
6+
{
7+
public interface ISystemService
8+
{
9+
void DoNothing();
10+
string ConvertText(string text, TextStyle style);
11+
Guid GenerateId();
12+
byte[] ReverseBytes(byte[] input);
13+
}
14+
}

src/IpcServiceSample.WebServer/Program.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
using JKang.IpcServiceFramework;
1+
using IpcServiceSample.ServiceContracts;
2+
using JKang.IpcServiceFramework;
23
using Microsoft.AspNetCore;
34
using Microsoft.AspNetCore.Hosting;
45
using Microsoft.Extensions.DependencyInjection;
56
using System;
7+
using System.Net;
68
using System.Threading;
79

810
namespace IpcServiceSample.WebServer
@@ -23,7 +25,8 @@ private static void StartIpcService(object state)
2325
{
2426
var serviceProvider = state as IServiceProvider;
2527
new IpcServiceHostBuilder(serviceProvider)
26-
.AddNamedPipeEndpoint("ep1", "pipeName")
28+
.AddNamedPipeEndpoint<IComputingService>("computingEndpoint", "pipeName")
29+
.AddTcpEndpoint<ISystemService>("systemEndpoint", IPAddress.Loopback, 45684)
2730
.Build()
2831
.Run();
2932
}

src/IpcServiceSample.WebServer/Startup.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public void ConfigureServices(IServiceCollection services)
1616
.AddIpc()
1717
.AddNamedPipe()
1818
.AddService<IComputingService, ComputingService>()
19-
;
19+
.AddService<ISystemService, SystemService>();
2020
}
2121

2222
public void Configure(IApplicationBuilder app, IHostingEnvironment env)

src/JKang.IpcServiceFramework.Client/IpcServiceClient.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ private static IpcRequest GetRequest(Expression exp, MyInterceptor interceptor)
7878

7979
return new IpcRequest
8080
{
81-
InterfaceName = typeof(TInterface).AssemblyQualifiedName,
8281
MethodName = interceptor.LastInvocation.Method.Name,
8382
Parameters = interceptor.LastInvocation.Arguments,
8483
};

0 commit comments

Comments
 (0)