MediatR.IPC
4.1.0
See the version list below for details.
dotnet add package MediatR.IPC --version 4.1.0
NuGet\Install-Package MediatR.IPC -Version 4.1.0
<PackageReference Include="MediatR.IPC" Version="4.1.0" />
paket add MediatR.IPC --version 4.1.0
#r "nuget: MediatR.IPC, 4.1.0"
// Install MediatR.IPC as a Cake Addin #addin nuget:?package=MediatR.IPC&version=4.1.0 // Install MediatR.IPC as a Cake Tool #tool nuget:?package=MediatR.IPC&version=4.1.0
MediatR.IPC
A simple IPC proxy for MediatR requests.
How it works
MediatR.IPC provides two public interfaces: a client and a server. The client interface implements ISender
. The server takes a dependency on ISender
, usually resolved via a DI container. Messages from the client to the server are serialized with protobuf-net. The IPC transport can use Named Pipes or Unix Domain Sockets.
Usage
All IPC requests need to be registered. This can be done via assembly scanning or explicit registration. Since IPCs have different app domains, the registration will need to be done on the client and server. I recommend using a shared assembly which does this for you.
Process 1 (Command Handler)
[ProtoContract(ImplicitFields = ImplicitFields.AllPublic)]
public record MyFancyCommand : IRequest<bool>
{
public string Message { get; init; } = string.Empty;
}
public static async Task Main(string[] args)
{
// Register the IPC requests on startup
IPCMediator.UseTransport(IPCTransport.NamedPipe);
IPCMediator.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
.WithAttribute<IPCRequestAttribute>()
.Where(...);
IPCMediator.RegisterType<MyFancyCommand>();
// Use the default runtime type model from protobuf-net
IPCMediator.TypeModel = RuntimeTypeModel.Default;
// Resolve the ISender, so the server can proxy incoming requests.
ISender sender = MyContainer.Resolve<ISender>();
// Run the server until the application is closed.
var server = new MediatorServerPool(sender, poolName: "MyRequestPool", poolSize: 8);
await server.Run();
}
Process 2 (Request sender)
public static async Task Main(string[] args)
{
// Register the requests, just like in Process 1
IPCMediator.UseTransport(IPCTransport.NamedPipe);
...
IPCMediator.RegisterType<MyFancyCommand>();
// Create an ISender, which can be consumed by the application.
ISender ipcSender = new MediatorClientPool(poolName: "MyRequestPool", poolSize: 8);
// All requests are sent via ipcSender are sent to and handled by Process 1,
// and the response is sent back to Process 2.
bool result = await ipcSender.Send<MyDto>(new MyFancyCommand { Message = "Hello!" });
Console.WriteLine(result);
}
Registration
All requests sent to the client need to be registered on the client and the server. This allows for quick resolution of types, and little overhead during runtime.
Transports
There are two supported transport types: Named Pipes and Unix Domain Sockets. Transport is specified with
IPCMediator.UseTransport(IPCTransport.UnixDomainSocket)
.WithOptions(new UnixDomainSocketOptions
{
SocketPrefix = "/tmp/",
SocketSuffix = ".sock",
});
You could also implement your own transport; a TCP transport for instance.
However, this can easily be expanded upon! Simply create an implementation of IStreamStratergy
.
Notifications
Notifications are a work in progress. NotificationHandler
s need to be registered in the DI container. IPC notifications would also need to be routed to the MediatorServer
. Pull requests are most welcome!
Exceptions
Currently, exceptions thrown by request handlers are not serialized, and no type information is preserved. Exceptions can be huge, and there is no garantue that the client process has a reference to the Exception
-type thrown. Ideas and suggestions are welcome!
Contributing
All forms of contribution are welcome! Here is a list of some much needed features.
- Request cancellation with
CancellationToken
- Dynamic buffers for requests in
MediatorServerBase
-
IPublisher
implementation - Routing of
INotification
toINotificationHandler
designated for IPC via DI container.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. 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. |
.NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.1 is compatible. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- MediatR (>= 11.1.0)
- protobuf-net.Core (>= 3.1.26)
-
net6.0
- MediatR (>= 11.1.0)
- protobuf-net.Core (>= 3.1.26)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.