Menees.Remoting 0.7.0-beta

The ID prefix of this package has been reserved for one of the owners of this package by NuGet.org. Prefix Reserved
.NET 6.0 .NET Framework 4.8
This is a prerelease version of Menees.Remoting.
There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package Menees.Remoting --version 0.7.0-beta
NuGet\Install-Package Menees.Remoting -Version 0.7.0-beta
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Menees.Remoting" Version="0.7.0-beta" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Menees.Remoting --version 0.7.0-beta
#r "nuget: Menees.Remoting, 0.7.0-beta"
#r directive can be used in F# Interactive, C# scripting and .NET Interactive. Copy this into the interactive tool or source code of the script to reference the package.
// Install Menees.Remoting as a Cake Addin
#addin nuget:?package=Menees.Remoting&version=0.7.0-beta&prerelease

// Install Menees.Remoting as a Cake Tool
#tool nuget:?package=Menees.Remoting&version=0.7.0-beta&prerelease

windows build & test Nuget

Remoting

This repo provides a simple RMI and IPC library for .NET Framework 4.8 and .NET 6.0+ applications. It's designed to help ease the migration from legacy WCF and .NET Remoting when porting code from .NET Framework to modern .NET. However, this library doesn't try to do all the things like WCF and .NET Remoting.

Menees.Remoting:

  • Prefers simplicity over performance.
  • Is designed for non-chatty communication.
  • Can't pass or return a .NET reference directly.
  • Requires values to be serialized going to and from the server.
  • Uses named pipes and a serializer of your choice (default is System.Text.Json).
  • Doesn't use or care about MarshalByRefObject, OperationContract, ServiceContract, etc.

RMI

Menees.Remoting provides RmiClient to invoke .NET interface methods in a remote RmiServer. The server process exposes a .NET interface for a given instance object. Then one or more client processes invoke .NET interface methods on the server's instance object. .NET's DispatchProxy.Create is used to generate the interface proxy, so clients can invoke the interface methods as normal C# calls.

[TestMethod]
public void HasherExample()
{
    const string ServerPath = "Menees.Remoting.RmiClientTests.HasherExample";

    using RmiServer<IHasher> server = new(new Hasher(), ServerPath);
    server.Start();

    using RmiClient<IHasher> client = new(ServerPath);
    IHasher proxy = client.CreateProxy();

    proxy.Hash(new byte[] { 1, 2, 3, 4 }).Length.ShouldBe(20);
    proxy.Hash("Testing").ShouldBe("0820b32b206b7352858e8903a838ed14319acdfd");
}

internal interface IHasher
{
    byte[] Hash(byte[] data);
    string Hash(string text);
}

internal class Hasher : IHasher
{
    public byte[] Hash(byte[] data)
    {
        using HashAlgorithm hasher = SHA1.Create();
        return hasher.ComputeHash(data);
    }

    public string Hash(string text)
    {
        byte[] hash = this.Hash(Encoding.UTF8.GetBytes(text));
        return string.Concat(hash.Select(b => $"{b:x2}"));
    }
}

For more usage examples see:

Due to the synchronous API of the underlying DispatchProxy.Invoke method, all the client invocations are sent synchronously to the server. The RmiClient can't do asynchronous calls to the RmiServer due to risks with sync over async. For more on DispatchProxy's lack of InvokeAsync support see #19349 and the comments for Migrating RealProxy Usage to DispatchProxy.

IPC

Menees.Remoting provides MessageClient to send a TIn-typed request message to a MessageServer and receive a TOut-typed response message. Message IPC only supports asynchronous calls, and the server requires a lambda that takes a TIn and returns a Task<TOut>.

[TestMethod]
public async Task Base64ExampleAsync()
{
    const string ServerPath = "Menees.Remoting.MessageNodeTests.Base64ExampleAsync";

    using MessageServer<byte[], string> server = new(data => Task.FromResult(Convert.ToBase64String(data)), ServerPath);
    server.Start();

    using MessageClient<byte[], string> client = new(ServerPath);
    string response = await client.SendAsync(new byte[] { 1, 2, 3, 4 }).ConfigureAwait(false);
    response.ShouldBe("AQIDBA==");
}

For more usage examples see:

No .NET Standard 2.0 Support

This library doesn't target .NET Standard 2.0 because that standard doesn't support:

Product Versions
.NET net6.0 net6.0-android net6.0-ios net6.0-maccatalyst net6.0-macos net6.0-tvos net6.0-windows net7.0 net7.0-android net7.0-ios net7.0-maccatalyst net7.0-macos net7.0-tvos net7.0-windows
.NET Framework net48
Compatible target framework(s)
Additional computed target framework(s)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
0.8.0-beta 51 10/9/2022
0.7.0-beta 73 9/14/2022
0.6.0-beta 76 9/14/2022
0.5.0-beta 50 9/3/2022
0.4.0-alpha 54 6/20/2022