-
Notifications
You must be signed in to change notification settings - Fork 13
Description
Is your feature request related to a problem? Please describe.
Nerdbank.MessagePack library is the successor to MessagePack-CSharp. I created a custom marshaller to implement Nerdbank.MessagePack into ServiceModel.Grpc:
public sealed class NerdbankMessagePackMarshallerFactory : IMarshallerFactory
{
private Nerdbank.MessagePack.MessagePackSerializer _serializer;
public NerdbankMessagePackMarshallerFactory()
{
_serializer = new MessagePackSerializer { PerfOverSchemaStability = true };
}
public Marshaller<T> CreateMarshaller<T>()
{
return new Marshaller<T>(Serialize, Deserialize<T>);
}
private void Serialize<T>(T value, SerializationContext context)
{
var shape = ReflectionTypeShapeProvider.Default.GetShape<T>();
_serializer.Serialize<T>(context.GetBufferWriter(), value, shape);
context.Complete();
}
private T Deserialize<T>(DeserializationContext context)
{
var shape = ReflectionTypeShapeProvider.Default.GetShape<T>();
return _serializer.Deserialize<T>(context.PayloadAsReadOnlySequence(), shape);
}
}
Nerdbank.MessagePack uses PolyType as a source generator. The models must annotated with the GenerateShape attribute or by adding a witness type for a type that isn't declared in the project.
My problem is that ServiceModel.Grpc also uses a source generator for the messages. The type of the value parameter in the Serialize method are like this:
ServiceModel.Grpc.Channel.Message<System.DateTime>
ServiceModel.Grpc.Channel.Message<Contract.MyModel>
Client.MyGrpcClients.Message<string, int, int, string, string, int, bool, int, bool, int, int>
depending on the method signatures in the service contract interface:
[ServiceContract]
public interface IDemo
{
[OperationContract]
string TestDateTime(DateTime dt);
[OperationContract]
void TestObjectProperty(MyModel myModel);
[OperationContract]
void MultipleParameters(string p1, int p2, int p3, string p4, string p5, int p6, bool p7, int p8, bool p9, int p10, int p11);
}
Client:
//Client:
// configure ServiceModel.Grpc.DesignTime to generate a source code for IDemo client proxy
[ImportGrpcService(typeof(IDemo))]
internal static partial class MyGrpcClients
{}
In the NerdbankMessagePackMarshallerFactory
above i use the ReflectionTypeShapeProvider.Default
, because the models are wrapped as generic types in source generated ServiceModel.Grpc.Channel.Message<T1, T2, ..>
or Client.MyGrpcClients.Message<T1, T2, ..>
.
Is there a way make this work without reflection? Using a witness is also not possible.
[GenerateShapeFor<Client.MyGrpcClients.Message<string, int, int, string, string, int, bool, int, bool, int, int>>] //Compiler error
partial class Witness;
CC: @AArnott