【发布时间】:2020-01-28 12:52:15
【问题描述】:
假设我有一个 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; }
}
我想用它来构造一个更复杂的消息对象并通过 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; }
}
那么,如何以最方便的可读方式创建这样的消息?我看到了一些选项,但它们都有缺点:
- 最直接的选择:i>
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
})
});
会工作,但我不想写很多代码来分配每个属性,而且我不能使用 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; }
}
}
var command = new CreateContact
{
Type = ContactTypeEnum.Single,
Addresses = addresses.Select(a => _mapper.Map<CreateContact.Address>(a)).ToList()
};
await _messageBus.Send<ICreateContact>(command);
看起来更好,但是如果我希望它实现ICreateContact/IAddress,那么编译器会告诉我是否错误地构造了消息?我不能这样做,因为如果我写CreateContact : ICreateContact,我的Addresses 字段必须是List<IAddress> 类型(即使我让Address 实现IAddress)。
总结一下我的问题:
- 是否可以避免中间类并使用选项 1 来自动映射属性(使用或不使用 Automapper)?
- 为每个服务中的消息契约创建强类型类是个好主意吗?
- 如果是这样 - 如何处理接口类型的嵌套属性?
- 如果不是 - 如果消息合约有 30 个字段,其中一个被重命名并且您需要知道哪个没有文档,该怎么办?
【问题讨论】:
标签: .net rabbitmq messaging masstransit