Ale*_*ich 4 .net messaging masstransit rabbitmq
假设我有一个 ASP.NET Core Web API 应用程序,并且我的操作方法之一接收IEnumerable<AddressModel> addresses,如下AddressModel所示:
public class AddressModel
{
public string Street { get; set; }
public string ZipCode { get; set; }
public string City { get; set; }
public string Country { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我想用它来构造一个更复杂的消息对象并通过 MassTransit 发送它 -Addresses将是一个嵌套属性,我将设置更多字段:
public interface ICreateContact
{
ContactTypeEnum Type { get; }
List<IAddress> Addresses { get; }
}
public interface IAddress
{
string Street { get; }
string ZipCode { get; }
string City { get; }
string Country { get; }
}
Run Code Online (Sandbox Code Playgroud)
那么,如何以最方便可读的方式创建这样的消息呢?我看到了一些选择,但它们都有缺点:
await _messageBus.Send<ICreateContact>(new {
Type = ContactTypeEnum.Single,
Addresses = addresses.Select(a => new
{
Street = a.Street,
ZipCode = a.ZipCode,
City = a.City,
Country = a.Country
})
});
Run Code Online (Sandbox Code Playgroud)
可以,但我不想编写大量代码来分配每个属性,而且我无法使用 Automapper,因为ICreateContact/IAddress.
public class CreateContact
{
public ContactTypeEnum Type { get; set; }
public List<Address> Addresses { get; set; }
public class Address
{
public string Street { get; set; }
public string ZipCode { get; set; }
public string City { get; set; }
public string Country { get; set; }
}
}
Run Code Online (Sandbox Code Playgroud)
var command = new CreateContact
{
Type = ContactTypeEnum.Single,
Addresses = addresses.Select(a => _mapper.Map<CreateContact.Address>(a)).ToList()
};
await _messageBus.Send<ICreateContact>(command);
Run Code Online (Sandbox Code Playgroud)
看起来更好,但是如果我希望它实现ICreateContact/IAddress,那么编译器会告诉我是否错误地构建了消息?我不能这样做,因为如果我写CreateContact : ICreateContact,我的Addresses字段必须是类型List<IAddress>(即使我制作AddressImplement IAddress)。
总结一下我的问题:
首先,您不需要直接类,只需使用另一个嵌套匿名类型来初始化地址列表即可。MassTransit 的消息初始值设定项按照约定执行类型之间的大部分映射,包括类型转换(字符串到 int、日期等)。
由于所有属性名称都匹配,因此您可以轻松使用:
await _messageBus.Send<ICreateContact>(new {
Type = ContactTypeEnum.Single,
Addresses = addresses
});
Run Code Online (Sandbox Code Playgroud)
它会使用输入地址中的元素来初始化地址列表。
其次,您对生产者的强类型类有疑问吗?这取决于。我绝对不会在消息生成器之外共享这些具体类型。如果您想要这种级别的属性类型/名称验证,您可以做到。只是在您的项目中需要管理更多的类。我见过一些团队需要工程师的指导,但更常见的是,我看到团队乐于放手并在存储库级别保护合同变更。
第三,您可以使具体类型具有正确的元素类型 (IAddress) 并向其中添加 Address 具体类型。这消除了数组类型问题,并且仍然允许您使用实现 IAddress 的 Address 具体类型。
第四,说真的,不要重命名属性!如果这是一个错误,请使用工具和 grep 全局修复它,以查找跨存储库的任何用法。但一旦投入生产,重命名可能会破坏一切。在这种情况下,添加一个新属性(拼写正确,无论如何)和更新的生产者最终发送这两个属性,并且一旦系统全面升级,就弃用原始属性。
文档中提供了有关 MassTransit 支持消息初始值设定项的更多详细信息。
| 归档时间: |
|
| 查看次数: |
2284 次 |
| 最近记录: |