StonyGrey.ObjectMapper 3.0.8

dotnet add package StonyGrey.ObjectMapper --version 3.0.8
NuGet\Install-Package StonyGrey.ObjectMapper -Version 3.0.8
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="StonyGrey.ObjectMapper" Version="3.0.8" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add StonyGrey.ObjectMapper --version 3.0.8
#r "nuget: StonyGrey.ObjectMapper, 3.0.8"
#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 StonyGrey.ObjectMapper as a Cake Addin
#addin nuget:?package=StonyGrey.ObjectMapper&version=3.0.8

// Install StonyGrey.ObjectMapper as a Cake Tool
#tool nuget:?package=StonyGrey.ObjectMapper&version=3.0.8

StonyGrey.ObjectMapper

StonyGrey.ObjectMapper is a GRPC-aware source generated object mapper. In addition to mapping POCOs, it generates extension methods that map between Protocol Buffers (Protobuf) classes generated by Grpc.Tools and domain classes provided by you.

Given a protobuf definition such as this:

package Protobuf;

enum TestEnum { One = 0; Two = 1; }

message TestMessage {
    string String = 1;
    int32 Int = 2;
    optional int32 Optional = 3;
    int32 NonOptional = 4;
    bytes Guid = 5;
    sint64 DateTime = 6;
    oneof OneOf {
        sint64 OneOfA = 7;
        sint64 OneOfB = 8;
    }
    TestEnum TestEnum = 9;
    bytes Data = 10;
    optional bytes OptionalData = 11;
}

Grpc.Tools will generate a C# class (that is too verbose in nature to include here). The StonyGrey.ObjectMapper will generate extension methods that map between this Grpc.Tools created class and a domain class created by you. For example:

namespace Domain
{
    public enum TestEnum { One, Two }

    public class TestMessage
    {
        public string? String { get; set; }
        public int Int { get; set; }
        public int? Optional { get; set; }
        public int NonOptional { get; set; }
        public long OneOfA { get; set; }
        public long OneOfB { get; set; }
        public DateTime DateTime { get; set; }
        public Guid Guid { get; set; }
        public TestEnum TestEnum { get; set; }
        public byte[] Data { get; set; } = Array.Empty<byte>();
        public byte[]? OptionalData { get; set; }
    }
}

Extension methods in a class annotated with the <code>MappingConversion</code> attribute will convert between incompatible types.

namespace Domain
{
    [MappingConversion]
    public static partial class MappingExtensions
    {
        public static ByteString MapToByteString(this Guid value)
            => ByteString.CopyFrom(value.ToByteArray());

        public static byte[] MapToByteArray(this ByteString value)
            => value == null ? Array.Empty<byte>() : value.ToByteArray();

    ...

    }
}

Usage

Please see the StonyGrey.ObjectMapper.Host project for a working example.

  1. Add the StonyGrey.ObjectMapper Nuget to your project.

  2. Use the <code>Map</code> attribute to define the source and target classes:

     [assembly: Map(typeof(Domain.TestMessage), typeof(Protobuf.TestMessage))]
     [assembly: Map(typeof(Protobuf.TestMessage), typeof(Domain.TestMessage), ContainingNamespaceKind.Destination)]
    
  3. Convert incompatible types in a class annotated with <code>MappingConversion</code>.

StonyGrey.ObjectMapper will generate extension methods with the following signatures:

public static DomainClass Map(this GrpcGeneratedClass self) {...}
public static GrpcGeneratedClass Map(this DomainClass self) {...}

The generated source can be found at YourProject->Dependencies->Analyzers->StonyGrey.ObjectMapper->StonyGrey.ObjectMapper.MapGenerator

Mapping

StonyGrey.ObjectMapper was built to address a specific problem and as such does not cover every scenario. It was tested with proto3 and Grpc.Tools 2.45.0.

Some additional detail on what is or is not supported follows.

Scalars

Everything is mapped one-to-one with the exception of <code>bytes</code> which is automatically mapped to/ from <code>Google.Protobuf.ByteString</code>.

Enumerations

Conversion is delegated to the caller but can be as simple as a cast.

Other Message Types

Message fields that are themselves messages will need <code>MapProtobuf</code> attributes declared. This allows this library to map an entire object graph.

Nested Types

Untested/ Unsupported.

Any

Untested/ Unsupported.

Oneof

This is supported by relying on the convention that only one of the properties will have a non-default value while all others will have the default value.

Maps

Untested/ Unsupported.

C# Types

Mapping between properties is attempted in the following order:

  1. Simple assignment
  2. Conversion using the <code>MappingConversion</code> annotated class.
  3. Map()

Collections/ repeated

The souce must implement <code>IEumerable<T></code> and the target <code>ICollection<T></code>.

Acknowledgements

StonyGrey.ObjectMapper is based on the InlineMapping project.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  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 netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos 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
3.0.8 77 2/20/2024
3.0.7 83 1/11/2024
3.0.6 102 12/12/2023
3.0.5 94 11/24/2023
3.0.4 99 10/20/2023
3.0.3 387 5/11/2023
3.0.2 354 11/10/2022
3.0.1 194 6/3/2022
3.0.0 150 5/5/2022
2.0.0 150 4/19/2022
1.0.3 167 4/3/2022
1.0.2 122 3/30/2022
1.0.1 123 3/6/2022
1.0.0 409 3/5/2022