gpt4 book ai didi

rebus - 我如何让 Rebus 确定接口(interface)的端点而不是该接口(interface)的实现

转载 作者:行者123 更新时间:2023-12-02 03:45:02 24 4
gpt4 key购买 nike

当我发送由 AutoMapper.Mapper.DynamicMap() 创建的实例时,我遇到了一个错误,其中 Rebus 似乎想要确定 DynamicMap 返回的代理类型的端点。此实例将包含 T 的实现,假设 T 是接口(interface)类型。

有没有办法让 Rebus 确定接口(interface)类型 T 而不是 DynamicMap() 返回的实现类型的端点?

我尝试使用 IDetermineMessageOwnership,但到目前为止运气不佳。

public static void Send<T>(this IBus bus, object source)
{
var message = Mapper.DynamicMap<T>(source);
bus.Send<T>(message);
}

提前致谢!

最佳答案

当然!在您的情况下,您可以创建自己的 IDetermineMessageOwnership 实现,这是 Rebus 用来将消息类型映射到端点的服务。

如果您想利用 Rebus 的现有逻辑,您可以装饰任何选定的策略并使用keep-looking-at-all-implemented-interfaces-until-one-can-be-mapped 像这样的策略:

Configure.With(adapter)
.(...)
.MessageOwnership(o => o.FromRebusConfigurationSection())
.Decorators(d => d.AddDecoration(DecorateOwnershipMapping)))
.CreateBus()
.Start();

DecorateOwnershipMapping 将在任何配置的顶部安装装饰器,如下所示:

void DecorateOwnershipMapping(ConfigurationBackbone b)
{
b.DetermineMessageOwnership = new CustomizedEndpointMapper(b.DetermineMessageOwnership);
}

一个可能的实现可能是这样的:

class CustomizedEndpointMapper : IDetermineMessageOwnership
{
readonly IDetermineMessageOwnership wrappedEndpointMapper;

public CustomizedEndpointMapper(IDetermineMessageOwnership wrappedEndpointMapper)
{
this.wrappedEndpointMapper = wrappedEndpointMapper;
}

public string GetEndpointFor(Type messageType)
{
var mappingCandidates = new[] {messageType}
.Concat(messageType.GetInterfaces())
.ToList();

foreach (var typeToTry in mappingCandidates)
{
try
{
return wrappedEndpointMapper.GetEndpointFor(typeToTry);
}
catch{}
}

throw new InvalidOperationException(string.Format("Could not determine the owner of message of type {0} - attempted to map the following types: {1}",
messageType, string.Join(", ", mappingCandidates)));
}
}

因此在尝试确定拥有端点时遍历具体类型以及所有继承的接口(interface)类型。

在您的情况下,我相信这在确定消息所有者时会完美无缺。唯一的问题是序列化程序很可能会提示,因为在收到消息时无法再次识别动态生成的类型。

因此,这个技巧也需要序列化器的定制。如果您使用的是(默认)JSON 序列化程序,您可能会像这样使用一些自定义解析器:

Configure.With(...)
.(...)
.Serialization(s => s.UseJsonSerializer()
.AddNameResolver(CustomNameResolver)
.AddTypeResolver(CustomTypeResolver))
.(...)

其中 CustomNameResolverCustomTypeResolver 是必须负责将类型映射到类型名称并将类型名称映射到可以反序列化为的类型的方法.为了使它与 AutoMapper 一起工作,您可能需要要么

a) 以某种方式使用 AutoMapper 查找接收到的消息的类型并从 CustomTypeResolver 返回该类型,或者

b) 自定义序列化器让 AutoMapper 以某种方式参与生成要返回的对象

但我必须承认,我不确定最后一部分是否会顺利进行。

最后一点:如果你成功地完成了这项工作,我建议你将你的配置拼写打包到 RebusConfigurer 上的可重用扩展方法中,这样你的端点就可以了

Configure.With(...)
.(...)
.UseMyFunkyAutoMapperMessagesJustTheWayILikeIt()
.CreateBus().Start();

在你所有的 Rebus 端点中......

如果您能告诉我这对您来说效果如何,我将不胜感激! :)

关于rebus - 我如何让 Rebus 确定接口(interface)的端点而不是该接口(interface)的实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17609531/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com