Pygmalions.Prism.Remoting 1.1.2

dotnet add package Pygmalions.Prism.Remoting --version 1.1.2
NuGet\Install-Package Pygmalions.Prism.Remoting -Version 1.1.2
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="Pygmalions.Prism.Remoting" Version="1.1.2" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Pygmalions.Prism.Remoting --version 1.1.2
#r "nuget: Pygmalions.Prism.Remoting, 1.1.2"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Pygmalions.Prism.Remoting as a Cake Addin
#addin nuget:?package=Pygmalions.Prism.Remoting&version=1.1.2

// Install Pygmalions.Prism.Remoting as a Cake Tool
#tool nuget:?package=Pygmalions.Prism.Remoting&version=1.1.2

Prism Remoting

This library contains a plugin to enable a proxy class to receive invocation data as a server, and a client generator to generate client proxies.

Concepts

Client

Remote client proxies are generated by RemoteClientGenerator (or its shared instance Remote). Their methods which are marked with Remote attributes are override to encode the invocation data (arguments) and send it to the Transporter and then wait and decode the return value.

The Transporter can be modified through IRemoteClient interface, and this property will never be null since you have to specify a transporter before creating a remote client.

Server

Server proxy is generated by the Prism Generator. If a class have any method marked with Remote attribute, then the RemotingPlugin will implement the IRemoteServer interface in its proxy class, which enable it to handle invocation data through HandleInvocation method.

In HandleInvocation method, the meta data token of the method to invoke will be firstly decoded, then, the invocation data will be decoded in the layout of the arguments of the chosen method. The chosen method will be invoked after all parameters are decoded, then its return value will be encoded into bytes and output from HandleInvocation method.

Transporter

This plugin does not want to force users to use a certain technique to transmission data, so we provide a interface ITransporter.

To implement a transporter, you have to finish these functions:

  1. Object selection.
  2. Data transmission.

Detailed steps are as follows:

  1. Add object ID to the head or tail of the invocation data package.
  2. Transmit the data to the correct server application.
  3. (By handlers in server application) Find the correct server proxy according to the object ID.
  4. (By handlers in server application) Invoke the HandleInvocation method.
  5. (By handlers in server application) Add object ID to the head or tail of the return-value data package.
  6. (By handlers in client application) Find the correct transporter transaction.
  7. Return the return-value data package.

How to Use

  1. Mark Remote attribute on methods to allow them to be remotely invoked.
  2. Implement ITransporter interface to provide data transmission ability.

Road Map

  • Server generator.
  • Client generator.
  • Built-in coders for asic value type.
  • Coder generator for arrays of basic value types.
  • Coder generator for structure types which composed of basic value types → Support third-party serializers by 'CustomCoderAttribute'.
  • Support async methods.

Suggestions About 'Data Coder'

Currently the built-in coders only support some built-in value types (integer, float, string, ...) and a few containers (array) or wrappers (Task and ValueTask), so we strongly recommend users use other serialization tools instead of the built-in ones. For example, protobuf-net is a good choice.

You can use it by implement ICoderProvider interface:

public class ProtobufProvider : ICoderProvider
{
    public static void Encode<TData>(TData data, MemoryStream stream)
    {
        ProtoBuf.Serializer.Serialize(stream, data);
    }

    public static TData Decode<TData>(MemoryStream stream)
        => ProtoBuf.Serializer.Deserialize<TData>(stream);
    
    public DataCoder GetEncoder(Type dataType)
    {
        return (code, stream) =>
        {
            code.Emit(OpCodes.Ldloc, stream);
            code.Emit(OpCodes.Call, 
                typeof(ProtobufProvider).
                    GetMethod(nameof(Encode), 
                        BindingFlags.Public | BindingFlags.Static)!
                    .MakeGenericMethod(dataType));
        };
    }

    public DataCoder GetDecoder(Type dataType)
    {
        return (code, stream) =>
        {
            code.Emit(OpCodes.Ldloc, stream);
            code.Emit(OpCodes.Call, 
                typeof(ProtobufProvider).
                    GetMethod(nameof(Decode), 
                        BindingFlags.Public | BindingFlags.Static)!
                    .MakeGenericMethod(dataType));
        };
    }
}
Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
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
1.1.2 363 10/31/2022
1.1.1 348 10/18/2022
1.0.0 356 10/17/2022