1k0n.Pipeline
2.2.0
dotnet add package 1k0n.Pipeline --version 2.2.0
NuGet\Install-Package 1k0n.Pipeline -Version 2.2.0
<PackageReference Include="1k0n.Pipeline" Version="2.2.0" />
paket add 1k0n.Pipeline --version 2.2.0
#r "nuget: 1k0n.Pipeline, 2.2.0"
// Install 1k0n.Pipeline as a Cake Addin #addin nuget:?package=1k0n.Pipeline&version=2.2.0 // Install 1k0n.Pipeline as a Cake Tool #tool nuget:?package=1k0n.Pipeline&version=2.2.0
1k0n Messaging Pipeline Library
Using 1k0n.Pipeline.StronglyTypedPipeline
Include the library and decalre a using to the _1k0n.Pipeline.StronglyTypedPipeline namespace.
using _1k0n.Pipeline.StronglyTypedPipeline;
Creating a Contract
The library will dynamically build the code at runtime for an interface defined contract.
[GenerateMessages]
public interface IMyMessageHandler
{
Task NewChatMessage(string username, string? message);
Task NewChatMessageResult(bool success, int? messageNum);
Task GetChatMessages(int start, int count);
Task ChatMessagesList(List<ChatMessage>? messages);
}
Decorate the interface with a GenerateMessagesAttribute so that the Pipeline will auto generate the messages needed for the contract.
All methods must return a Task
Create the Message Handler Client class
Create a class that implements the interface created above. The members of this class will be called when a message is received from the pipeline. The method that the sender calls, is the method that will be called on the receiver.
public class MyMessageHandlerClient : IMyMessageHandler
{
public MyMessageHandlerClient()
{
// you can use dependency injection to pass in any dependencies
}
public Task NewChatMessageResult(bool success, int? messageNum)
{
// Do something with the returned data
if (success)
{
...
}
}
public Task ChatMessagesList(List<ChatMessage>? messages)
{
// Do something with the returned data
ProcessMessages(messages);
}
// Don't implement messages we don't expect to receive
public Task NewChatMessage(string username, string? message) =>
throw new NotImplementedException();
public Task GetChatMessages(int start, int count) =>
throw new NotImplementedException();
}
Any messages that the client will not be receiving should throw an exception so that they are not accidently called by the program.
Create the client
To create a client that sends and recieves messages using a strongly-typed pipeline, it is easiest to use Dependency Injection.
Use the AddMessagePipeline<TContract, THandler> extension method provided by the library to setup the pipeline.
services.AddMessagePipeline<IMyMessageHandler, MyMessageHandlerClient>();
The pipeline can now be passed to other classes using Dependency Injection.
public class MyWorker
{
MessagePipeline<IMyMessageHandler> _pipeline;
public MyWorker(MessagePipeline<IMyMessageHandler> pipeline)
{
_pipeline = pipeline;
}
}
Create the Message Handler Server class
To create a server handler, create a class that implements the contract interface and the IPipelineAccess< TContract > interface. For each connection to the server the library will create a new scoped handler. When the IPipelineAccess interface is used, the library will pass in the pipeline object for the current connection. This allows the handler to reply to the correct client.
public class MyMessageHandlerServer : IMyMessageHandler, IPipelineAccess<IMyMessageHandler>
{
public MessagePipeline<IMyMessageHandler>? Pipeline { get; set; }
public MyMessageHandlerServer()
{
// you can use dependency injection to pass in any dependencies
}
public Task NewChatMessage(string username, string? message)
{
// process message
int messageId = AddMessageToDb(message);
// Send response
await Pipeline.Send.NewChatMessageResult(true, messageId);
}
public Task GetChatMessages(int start, int count)
{
// Lookup messages in a cache or database
var messages = GetMessagesFromDb(start, count);
// Send list back to client
await Pipeline.Send.ChatMessageList(messages);
}
// Don't implement messages we don't expect to receive
public Task NewChatMessageResult(bool success, int? messageNum) =>
throw new NotImplementedException();
public Task ChatMessagesList(List<ChatMessage>? messages) =>
throw new NotImplementedException();
}
To communicate between clients, use dependency injection to pass in a global server object.
Create the server
To create a server that accepts pipeline connections, use Dependency Injection.
services.AddMessagePipelineServer<IMyMessageHandler, MyMessageHandler>();
The pipeline server can now be passed to another class using Dependency Injection.
public class MyServer
{
MessagePipelineServer<IMyMessageHandler> _pipelineServer;
public MyServer(MessagePipelineServer<IMyMessageHandler> pipelineServer)
{
_pipelineServer = pipelineServer;
}
}
Then start the pipeline listening.
if (_pipelineServer.OpenServerIP("127.0.0.1", 10000) == false)
{
// handle error
}
Sending messages through the pipeline
To send strongly typed messages on the pipeline, call the methods on the Send property of the pipeline object. The Send property is declared as the interface type of the contract.
// On the client
public async Task SendMessage(string? message)
{
await _pipeline.Send.NewChatMessage("LocalUserName", message);
}
// On the server handler
public async Task NewChatMessage(string username, string? message)
{
// process message
...
// Send response if needed
await Pipeline.Send.NewChatMessageResult(true, messageId++);
}
On the sever, the NewChatMessage(string username, string? message) method will be called on the handler with the data that was sent by the client. The server can then respond to the client if needed.
copyright © 2022 John Meyer Jr. - Usage instructions for the 1k0n.Pipeline library -
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net6.0
- Microsoft.Extensions.DependencyInjection (>= 6.0.0)
- Microsoft.Extensions.Logging (>= 6.0.0)
- System.IO.Pipelines (>= 6.0.0)
- System.Text.Json (>= 6.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.