Skip to content

Could I use different types for publisher and consumer #1292

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
WeihanLi opened this issue Oct 14, 2021 · 3 comments
Closed

Could I use different types for publisher and consumer #1292

WeihanLi opened this issue Oct 14, 2021 · 3 comments

Comments

@WeihanLi
Copy link
Contributor

Currently, my publisher and consumer are different projects, they're separated without any shared component,
it seemed when I publish a message it would write the message type info into the RabbitMQ message, and the consumer would try to deserialize the message according to the message type info, while the message type is not exists, so I get an error like follows:

{
    "RoutingKey": "test-queue-1",
    "Exchange": "test-exchange",
    "Queue": "test-queue-1",
    "Exception": "System.IO.FileNotFoundException: Could not load file or assembly 'AspNetCoreSample, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified.\r\nFile name: 'AspNetCoreSample, Culture=neutral, PublicKeyToken=null'\r\n   at System.Reflection.RuntimeAssembly.nLoad(AssemblyName fileName, String codeBase, RuntimeAssembly assemblyContext, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, AssemblyLoadContext assemblyLoadContext)\r\n   at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, StackCrawlMark& stackMark, AssemblyLoadContext assemblyLoadContext)\r\n   at System.Reflection.Assembly.Load(AssemblyName assemblyRef, StackCrawlMark& stackMark, AssemblyLoadContext assemblyLoadContext)\r\n   at System.Reflection.Assembly.Load(AssemblyName assemblyRef)\r\n   at EasyNetQ.DefaultTypeNameSerializer.GetTypeFromTypeNameKey(TypeNameKey typeNameKey)\r\n   at EasyNetQ.DefaultTypeNameSerializer.<>c.<DeSerialize>b__3_0(String t)\r\n   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)\r\n   at EasyNetQ.DefaultTypeNameSerializer.DeSerialize(String typeName)\r\n   at EasyNetQ.DefaultMessageSerializationStrategy.DeserializeMessage(MessageProperties properties, Byte[] body)\r\n   at EasyNetQ.RabbitAdvancedBus.<>c__DisplayClass16_0.<Consume>b__0(Byte[] body, MessageProperties properties, MessageReceivedInfo messageReceivedInfo, CancellationToken cancellationToken)\r\n   at EasyNetQ.RabbitAdvancedBus.<>c__DisplayClass17_0.<Consume>b__0(Byte[] body, MessageProperties properties, MessageReceivedInfo receivedInfo, CancellationToken cancellationToken)\r\n   at EasyNetQ.Consumer.HandlerRunner.InvokeUserMessageHandlerInternalAsync(ConsumerExecutionContext context, CancellationToken cancellationToken)\r\n\r\n",
    "Message": "{\"Date\":\"2021-10-14T11:19:34.4283886Z\",\"TemperatureC\":0,\"TemperatureF\":32,\"Summary\":\"test\"}",
    "DateTime": "2021-10-14T11:19:34.4594967Z",
    "BasicProperties": {
        "ContentType": null,
        "ContentEncoding": null,
        "Headers": {
            "x-retry-limit": 10
        },
        "DeliveryMode": 0,
        "Priority": 0,
        "CorrelationId": "23fff764-ab44-4145-9832-132b2fd2fa52",
        "ReplyTo": null,
        "Expiration": null,
        "MessageId": "a8f45ddf-adbb-4f3b-bec8-713868b8ef18",
        "Timestamp": 0,
        "Type": "AspNetCoreSample.WeatherForecast, AspNetCoreSample",
        "UserId": null,
        "AppId": null,
        "ClusterId": null,
        "ContentTypePresent": false,
        "ContentEncodingPresent": false,
        "HeadersPresent": true,
        "DeliveryModePresent": false,
        "PriorityPresent": false,
        "CorrelationIdPresent": true,
        "ReplyToPresent": false,
        "ExpirationPresent": false,
        "MessageIdPresent": true,
        "TimestampPresent": false,
        "TypePresent": true,
        "UserIdPresent": false,
        "AppIdPresent": false,
        "ClusterIdPresent": false
    }
}

Wondering that is there any way to support the different model types

@zidad
Copy link
Member

zidad commented Oct 14, 2021

Hi @WeihanLi,

It is designed to use a shared component, however you can simply implement and register your own ITypeNameSerializer in both projects to change this behavior.

Hope this helps?

@WeihanLi
Copy link
Contributor Author

@zidad thanks for your help, it does help. As it's designed to use a shared component, I would move them into a shared component.

@WeihanLi
Copy link
Contributor Author

Shared my initial type name serializer with fallback, hope it would help

public sealed class FallbackTypeNameSerializer : ITypeNameSerializer
{
    private readonly ITypeNameSerializer _typeNameSerializer;

    public FallbackTypeNameSerializer(ITypeNameSerializer typeNameSerializer)
    {
        _typeNameSerializer = typeNameSerializer;
    }

    public bool FallbackFirst { get; set; }

    public Func<Type, string> FallbackSerializer { get; set; }
    public Func<string, Type> FallbackDeSerializer { get; set; }

    public string Serialize(Type type)
    {
        if (FallbackFirst)
        {
            try
            {
                if (FallbackSerializer != null)
                {
                    return FallbackSerializer.Invoke(type);
                }
            }
            catch
            {
                // ignore
            }
            return _typeNameSerializer.Serialize(type);
        }
        else
        {
            try
            {
                return _typeNameSerializer.Serialize(type);
            }
            catch
            {
                if (FallbackSerializer == null)
                {
                    throw;
                }
                else
                {
                    return FallbackSerializer.Invoke(type);
                }
            }
        }
    }

    public Type DeSerialize(string typeName)
    {
        if (FallbackFirst)
        {
            try
            {
                if (FallbackDeSerializer != null)
                {
                    return FallbackDeSerializer.Invoke(typeName);
                }
            }
            catch
            {
                // ignore
            }
            return _typeNameSerializer.DeSerialize(typeName);
        }
        else
        {
            try
            {
                return _typeNameSerializer.DeSerialize(typeName);
            }
            catch
            {
                if (FallbackDeSerializer == null)
                {
                    throw;
                }
                return FallbackDeSerializer.Invoke(typeName);
            }
        }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants