在嘗試使用Service Fabric遠程處理時,我有一些數據類型未正確序列化。這導致我很多問題。服務結構遠程處理串行器
從文檔看來,所有東西都需要用[DataContract]進行修飾。在某些測試類型上使用它之後,它確實顯示它們序列化正確。
但坦率地說,我不想裝飾一切。這對我來說將是一個巨大的倒退。我寧願使用自定義序列化。
這個documentation似乎表明它可以註冊一個自定義序列化器,但它似乎只用於有狀態服務。我主要使用無狀態服務進行遠程處理。
在嘗試使用Service Fabric遠程處理時,我有一些數據類型未正確序列化。這導致我很多問題。服務結構遠程處理串行器
從文檔看來,所有東西都需要用[DataContract]進行修飾。在某些測試類型上使用它之後,它確實顯示它們序列化正確。
但坦率地說,我不想裝飾一切。這對我來說將是一個巨大的倒退。我寧願使用自定義序列化。
這個documentation似乎表明它可以註冊一個自定義序列化器,但它似乎只用於有狀態服務。我主要使用無狀態服務進行遠程處理。
當前遠程處理堆棧要求您的類型使用DataContract。據說這個團隊在不久的將來會發佈一個新的遠程堆棧,它包含插入自定義序列化的能力以及性能方面的許多改進,但目前還沒有。
與此同時,解決方法是讓所有的代理服務器都得到string
或byte[]
或類似的東西,並使用類似JSON.Net的方式手動處理序列化/反序列化。就我個人而言,我會咬緊牙關,讓你的類型Data Contract Serializable直到新的遠程位可用。
感謝您的信息。這目前聽起來像是最好的方法。 – Telavian
隨着Service Fabric V2 Remoting的發佈,現在可以實現了。有關更多詳細信息,請參閱here。
這裏是我使用過的遠程處理序列化程序的一個實現,但在你的情況下,文檔中的JSON例子可能就足夠了。
public class MessagePackMessageFactory : IServiceRemotingMessageBodyFactory
{
public IServiceRemotingRequestMessageBody CreateRequest(string interfaceName, string methodName, int numberOfParameters)
{
return new MessagePackRemotingRequestMessageBody(numberOfParameters);
}
public IServiceRemotingResponseMessageBody CreateResponse(string interfaceName, string methodName)
{
return new MessagePackServiceRemotingResponseMessageBody();
}
}
[MessagePackObject]
public class MessagePackRemotingRequestMessageBody : IServiceRemotingRequestMessageBody
{
[Key(0)]
public object Value;
public MessagePackRemotingRequestMessageBody()
{
}
public MessagePackRemotingRequestMessageBody(int parameterInfos)
{
}
public void SetParameter(int position, string paramName, object parameter)
{
Value = parameter;
}
public object GetParameter(int position, string paramName, Type paramType)
{
return Value;
}
}
[MessagePackObject]
public class MessagePackServiceRemotingResponseMessageBody : IServiceRemotingResponseMessageBody
{
[Key(0)]
public object Response;
public object Get(Type paramType)
{
// ignore paramType?
return Response;
}
public void Set(object response)
{
Response = response;
}
}
public class ServiceRemotingResponseMessagePackMessageBodySerializer : IServiceRemotingResponseMessageBodySerializer
{
public OutgoingMessageBody Serialize(IServiceRemotingResponseMessageBody responseMessageBody)
{
if (!(responseMessageBody is MessagePackServiceRemotingResponseMessageBody body))
{
return new OutgoingMessageBody(new[] { new ArraySegment<byte>(new byte[0]) });
}
var bytes = MessagePackSerializer.Serialize(body, ServiceFabricResolver.Instance);
return new OutgoingMessageBody(new[] { new ArraySegment<byte>(bytes) });
}
public IServiceRemotingResponseMessageBody Deserialize(IncomingMessageBody messageBody)
{
using (var stream = messageBody.GetReceivedBuffer())
{
if (stream.Length == 0)
{
return new MessagePackServiceRemotingResponseMessageBody();
}
var body = MessagePackSerializer.Deserialize<MessagePackServiceRemotingResponseMessageBody>(stream, ServiceFabricResolver.Instance);
return body;
}
}
}
public class ServiceRemotingMessagePackSerializationProvider : IServiceRemotingMessageSerializationProvider
{
public IServiceRemotingRequestMessageBodySerializer CreateRequestMessageSerializer(Type serviceInterfaceType,
IEnumerable<Type> requestBodyTypes)
{
return new ServiceRemotingRequestMessagePackMessageBodySerializer();
}
public IServiceRemotingResponseMessageBodySerializer CreateResponseMessageSerializer(Type serviceInterfaceType, IEnumerable<Type> responseBodyTypes)
{
return new ServiceRemotingResponseMessagePackMessageBodySerializer();
}
public IServiceRemotingMessageBodyFactory CreateMessageBodyFactory()
{
return new MessagePackMessageFactory();
}
}
public class ServiceRemotingRequestMessagePackMessageBodySerializer : IServiceRemotingRequestMessageBodySerializer
{
public OutgoingMessageBody Serialize(IServiceRemotingRequestMessageBody serviceRemotingRequestMessageBody)
{
if (serviceRemotingRequestMessageBody == null) return null;
if (!(serviceRemotingRequestMessageBody is MessagePackRemotingRequestMessageBody body))
{
return new OutgoingMessageBody(new[] { new ArraySegment<byte>(new byte[0]) });
}
var bytes = MessagePackSerializer.Serialize(body, ServiceFabricResolver.Instance);
return new OutgoingMessageBody(new[] { new ArraySegment<byte>(bytes) });
}
public IServiceRemotingRequestMessageBody Deserialize(IncomingMessageBody messageBody)
{
using (var stream = messageBody.GetReceivedBuffer())
{
if (stream.Length == 0)
{
return new MessagePackRemotingRequestMessageBody();
}
var body = MessagePackSerializer.Deserialize<MessagePackRemotingRequestMessageBody>(stream, ServiceFabricResolver.Instance);
return body;
}
}
}
'從文檔看來,一切都需要使用[DataContract] .'裝飾,你不必 – Mardoxx
這是真的。 [DataContract]會嘗試將其可能的序列化。但是無法序列化的東西需要明確的幫助。 – Telavian