轨道交通。使用在不同命名空间中定义的相同对象
MassTransit. Consume equal objects defined in different namespaces
首先,请原谅我的英语,它很糟糕。我将 MassTransit 与 Azure 服务总线一起用于微服务之间的异步通信。根据它们自己的定义,并且为了避免在它们之间产生依赖关系,在不同微服务之间发送的消息在它们各自中定义,也就是说,它们是不同命名空间的一部分。 MassTransit 的自动管理导致队列和主题由对象类型管理,这可以防止消费消息的微服务接收微服务发布者发送的消息。同样的事情发生在两个 class 具有相同属性但具有不同 class 名称的同一命名空间中。
有什么办法可以解决吗?
我想到的选项是:
- 从目标地址的端点中删除命名空间,仅使用 class 的名称命名。
- MassTransit 可以根据对象的序列化来管理队列和主题的创建,而不是根据对象类型来管理(也许通过某种类型的包装对象?)
我举个例子希望能帮助你理解问题。
//FIRST PROGRAM - MESSAGE CONSUMER
namespace Consumer
{
public class Example
{
public string PropOne { get; set; }
public string PropTwo { get; set; }
}
public class ExampleConsumer :
IConsumer<Example>
{
public List<Example> ConsumedTestObjectList { get; } = new List<Example>();
//THIS METHOD NEVER CALL !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
public Task Consume(ConsumeContext<ExampleConsumer> context)
{
ConsumedTestObjectList.Add(context.Message);
return Task.CompletedTask;
}
}
public class ConsumerProgram
{
public static void Main()
{
var bus = Bus.Factory.CreateUsingAzureServiceBus(sbc =>
{
var host = sbc.Host("connectionString", h => {});
});
sbc.ReceiveEndpoint(host, e =>
{
e.Consumer<ConsumerProgram.Example>(context =>
{
return Console.Out.WriteLineAsync($"Message Received: {JsonConvert.SerializeObject(context.Message)}");
});
});
bus.Start(); // This is important!
Console.WriteLine("Press any key to exit");
Console.ReadKey();
bus.Stop();
}
}
}
//SECOND PROGRAM - MESSAGE PUBLISHER
namespace Publisher
{
public class Example
{
public string PropOne { get; set; }
public string PropTwo { get; set; }
}
public class PublisherProgram
{
public static void Main()
{
var bus = Bus.Factory.CreateUsingAzureServiceBus(sbc =>
{
var host = sbc.Host("connectionString", h => {});
});
bus.Start(); // This is important!
//send new instance of Publisher.Example
var example = new Example() { PropOne = "1", PropTwo = "2" };
bus.Publish(example);
Console.WriteLine("Press any key to exit");
Console.ReadKey();
bus.Stop();
}
}
}
非常感谢。
问候
博尔哈
消息类型和生成的名称是 MassTransit 中的一个关键概念。如果你想避免在项目之间共享程序集,那很好,但你需要匹配整个接口(或 class,在你的情况下)名称,包括命名空间,否则它将无法正确路由。
是的,您可以覆盖实体名称格式化程序以更改主题的命名方式,但它不会更改消息反序列化的消息类型要求(按类型发生)。
因此这里的建议是为合同使用相同的命名空间,即使它们在不同的项目中也是如此。
首先,请原谅我的英语,它很糟糕。我将 MassTransit 与 Azure 服务总线一起用于微服务之间的异步通信。根据它们自己的定义,并且为了避免在它们之间产生依赖关系,在不同微服务之间发送的消息在它们各自中定义,也就是说,它们是不同命名空间的一部分。 MassTransit 的自动管理导致队列和主题由对象类型管理,这可以防止消费消息的微服务接收微服务发布者发送的消息。同样的事情发生在两个 class 具有相同属性但具有不同 class 名称的同一命名空间中。
有什么办法可以解决吗? 我想到的选项是:
- 从目标地址的端点中删除命名空间,仅使用 class 的名称命名。
- MassTransit 可以根据对象的序列化来管理队列和主题的创建,而不是根据对象类型来管理(也许通过某种类型的包装对象?)
我举个例子希望能帮助你理解问题。
//FIRST PROGRAM - MESSAGE CONSUMER
namespace Consumer
{
public class Example
{
public string PropOne { get; set; }
public string PropTwo { get; set; }
}
public class ExampleConsumer :
IConsumer<Example>
{
public List<Example> ConsumedTestObjectList { get; } = new List<Example>();
//THIS METHOD NEVER CALL !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
public Task Consume(ConsumeContext<ExampleConsumer> context)
{
ConsumedTestObjectList.Add(context.Message);
return Task.CompletedTask;
}
}
public class ConsumerProgram
{
public static void Main()
{
var bus = Bus.Factory.CreateUsingAzureServiceBus(sbc =>
{
var host = sbc.Host("connectionString", h => {});
});
sbc.ReceiveEndpoint(host, e =>
{
e.Consumer<ConsumerProgram.Example>(context =>
{
return Console.Out.WriteLineAsync($"Message Received: {JsonConvert.SerializeObject(context.Message)}");
});
});
bus.Start(); // This is important!
Console.WriteLine("Press any key to exit");
Console.ReadKey();
bus.Stop();
}
}
}
//SECOND PROGRAM - MESSAGE PUBLISHER
namespace Publisher
{
public class Example
{
public string PropOne { get; set; }
public string PropTwo { get; set; }
}
public class PublisherProgram
{
public static void Main()
{
var bus = Bus.Factory.CreateUsingAzureServiceBus(sbc =>
{
var host = sbc.Host("connectionString", h => {});
});
bus.Start(); // This is important!
//send new instance of Publisher.Example
var example = new Example() { PropOne = "1", PropTwo = "2" };
bus.Publish(example);
Console.WriteLine("Press any key to exit");
Console.ReadKey();
bus.Stop();
}
}
}
非常感谢。
问候
博尔哈
消息类型和生成的名称是 MassTransit 中的一个关键概念。如果你想避免在项目之间共享程序集,那很好,但你需要匹配整个接口(或 class,在你的情况下)名称,包括命名空间,否则它将无法正确路由。
是的,您可以覆盖实体名称格式化程序以更改主题的命名方式,但它不会更改消息反序列化的消息类型要求(按类型发生)。
因此这里的建议是为合同使用相同的命名空间,即使它们在不同的项目中也是如此。