【问题标题】:Cannot access value of an interface type in azure service bus queue with masstransit无法使用 masstransit 访问 azure 服务总线队列中接口类型的值
【发布时间】:2020-01-10 13:18:04
【问题描述】:

我正在使用masstransit 向Azure 服务总线队列发送一条消息,其中消息模型接口本身具有另一个接口。我的消息架构是这样的:

public interface IMyMessage
{
    Guid NormalProp1 { get; set; }

    IVariableProp VariableProp { get; set; }
}

public interface IVariableProp
{

}

这里 IvariableProp 是一个接口,因为我想在其中发送可变类型的数据。喜欢:

public class VarietyProp1 : IVariableProp
{
    public Guid VarietyGuid1 { get; set; }
}

public class YetAnotherVarietyProp : IVariableProp
{
    public Guid YetAnotherVarietyGuid { get; set; }
    public bool YetAnotherVarietyBool { get; set; }
}

最后我的具体信息是:

public class MyConcreteMessage : IMyMessage
{
    public Guid NormalProp1 { get; set; }

    public IVariableProp VariableProp { get; set; }
}

我已将具体消息的一个实例发送到 azure 服务总线队列。具体消息如下:

    var variety1 = new MyConcreteMessage()
                       {
                           NormalProp1 = Guid.NewGuid(),
                           VariableProp = new VarietyProp1()
                                              {
                                                  VarietyGuid1 = Guid.NewGuid()
                                              }
                       };

此消息正在发送到 Azure 服务总线,没有任何问题,并且所有值都已正确发送。 (我检查了 azure service bus explorer)。

当我尝试使用 masstransit 使用 azure 功能使用消息时出现问题。在我的 Iconsumer 代码中,VariableProp 的值为 null。我的天蓝色功能代码如下:

        using (var dependencyScope = Program.AppDependencyResolver.BeginScope())
        {

            var scopedDependencyResolver = dependencyScope.Resolve<IDependencyResolver>();
            IOperationContext operationContext = dependencyScope.Resolve<OperationContext>();
            var serviceTriggerConfiguration = dependencyScope.Resolve<IServiceBusConsumerConfig>();


            var logger = dependencyScope.Resolve<ILogger>();

            logger.Info(() => $"ConsumeEventsFromQueue function is triggered");
            string convertedMessage = Encoding.UTF8.GetString(message.Body, 0, message.Body.Length);
            var retryCount = serviceTriggerConfiguration.RetryCount;
            var interval = serviceTriggerConfiguration.IntervalInMilliSeconds;
            var receiver = Bus.Factory.CreateBrokeredMessageReceiver(
                binder,
                cfg =>
                {
                    cfg.CancellationToken = cancellationToken;
                    cfg.SetLog(traceWriter);
                    cfg.UseRetry(x => x.Interval(retryCount, interval));
                    cfg.Consumer(() => scopedDependencyResolver.Resolve<EventConsumer>());

                });
            await receiver.Handle(message);

我的消费者代码是:

public class EventConsumer:IConsumer<IMyMessage>
{
    public async Task Consume(ConsumeContext<IMyMessage> context)
    {
        var message = context.Message;
    }
}

在消费者代码中,我无法获得 VariableProp 的值。当我设置调试指针时,它显示如下:

但是当我在我的函数中设置调试指针并将正文的字节数组转换为字符串时,我可以看到 VariableProp 的值。

我怀疑当通过代码调用消费者时该值正在丢失/封装:

cfg.Consumer(() => scopedDependencyResolver.Resolve<EventConsumer>());

我想要的是从消费者那里访问 VariableProp 的值。我能做什么?

【问题讨论】:

    标签: serialization .net-core azureservicebus masstransit azure-servicebus-queues


    【解决方案1】:

    这不是 MassTransit 问题,而是序列化问题。当您反序列化IMyMessage 时,它会将IVariableProp 反序列化为IVariableProp——即没有属性的接口。这是因为无法从接口定义中知道哪个具体类型应该隐藏在IVariableProp 后面。

    这是一篇不错的博文,详细介绍了问题和解决方案:http://appetere.com/post/serializing-interfaces-with-jsonnet

    我个人的建议是避免这样做。使您的消息合同尽可能简单明了。我什至不确定上述解决方案是否适用于 MassTransit。如果您想走上疯狂之路并继续使用这种方法,我将提供一条建议:可以使用单例 JsonMessageSerializer.SerializerSettings 配置 MassTransit JSON 序列化器设置。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-10
      • 1970-01-01
      • 2015-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-25
      相关资源
      最近更新 更多