除了 AutoMapper 中的 ForMember 方法之外,是否还有其他自定义映射方法?

Is there any alternative way of custom mapping aside from the ForMember method in AutoMapper?

我有复杂的模型 (SyncBillToPartyMaster),我想自定义映射到我的简单 POCO class。

Mapper.CreateMap<SyncBillToPartyMaster, CustomerAddress>()
.ForMember(d => d.CustomerId, o => o.MapFrom(src => src.DataArea.BillToPartyMaster.CustomerParty.PartyIDs.ID.Value))
.ForMember(d => d.CustomerAddressId, o => o.MapFrom(src => src.DataArea.BillToPartyMaster.PartyIDs.ID.Value))
.ForMember(d => d.City, o => o.MapFrom(src => src.DataArea.BillToPartyMaster.Location.Address.CityName))
.ForMember(d => d.State, o => o.MapFrom(src => src.DataArea.BillToPartyMaster.Location.Address.CountrySubDivisionCode.Value))
.ForMember(d => d.Country, o => o.MapFrom(src => src.DataArea.BillToPartyMaster.Location.Address.CountryCode.Value))
.ForMember(d => d.Zip, o => o.MapFrom(src => src.DataArea.BillToPartyMaster.Location.Address.PostalCode.Value))
.ForMember(d => d.Address1, o => o.MapFrom(src => src.DataArea.BillToPartyMaster.Location.Address.AddressLine[0].Value))
.ForMember(d => d.Address2, o => o.MapFrom(src => src.DataArea.BillToPartyMaster.Location.Address.AddressLine[1].Value))
.ForMember(d => d.Address3, o => o.MapFrom(src => src.DataArea.BillToPartyMaster.Location.Address.AddressLine[2].Value))
.ForMember(d => d.Phone1, o => o.MapFrom(src => GetContact(src.DataArea.BillToPartyMaster, "phone")))
.ForMember(d => d.Fax1, o => o.MapFrom(src => GetContact(src.DataArea.BillToPartyMaster, "fax")))
.ForMember(d => d.MaintenanceCustomerId, o => o.MapFrom(src => src.DataArea.BillToPartyMaster.LastModificationPerson.IDs[0].Value))
.ForMember(d => d.MaintenanceUser, o => o.MapFrom(src => src.DataArea.BillToPartyMaster.LastModificationPerson.Name.Value))
.ForMember(d => d.MaintenanceDate, o => o.MapFrom(src => DateTime.UtcNow));

如您所见,使用 AutoMapper 的 ForMember 方法将我的复杂模型 SyncBillToPartyMaster 映射到 CustomerAddress 非常繁琐。除了使用 ForMember 方法之外,还有其他方法可以使它变得优雅吗?

顺便说一下,除了 SyncBillToPartyMaster 之外,我还有更多、更复杂的模型。如果有另一种方法可以实现我的目标,我不想以同样的方式做它们。

不要使用 AutoMapper,这里没有匹配的东西。仅使用 "new" 运算符并自行设置所有内容,您并没有节省任何东西。

我在 Automapper 中阅读了一些上下文,我找到了 ITypeConverter<in T, out TU> 接口,我可以在其中实现自定义映射器 class 并进行自定义映射。为了注册我的自定义映射器,我使用了 Mapper.CreateMap<T,TU>().ConvertUsing().

这是我的自定义映射器:

public class CustomerAddressBillToPartyMasterMapper : ITypeConverter<SyncBillToPartyMaster, CustomerAddress>
    {
        public CustomerAddress Convert(ResolutionContext context)
        {
            var syncBillToPartyMaster = context.SourceValue as SyncBillToPartyMaster;

            if (syncBillToPartyMaster == null)
                return null;

            var customerAddressesSource = syncBillToPartyMaster.DataArea.BillToPartyMaster;

            return new CustomerAddress
            {
                CustomerId = customerAddressesSource.CustomerParty.PartyIDs.ID.Value,
                CustomerAddressId = customerAddressesSource.PartyIDs.ID.Value,
                City = customerAddressesSource.Location.Address.CityName,
                State = customerAddressesSource.Location.Address.CountrySubDivisionCode.Value,
                Country = customerAddressesSource.Location.Address.CountryCode.Value,
                Zip = customerAddressesSource.Location.Address.PostalCode.Value,
                Address1 = customerAddressesSource.Location.Address.AddressLine[0].Value,
                Address2 = customerAddressesSource.Location.Address.AddressLine[1].Value,
                Address3 = customerAddressesSource.Location.Address.AddressLine[2].Value,
                Phone1 = GetContact(customerAddressesSource, "phone"),
                Fax1 = GetContact(customerAddressesSource, "fax"),
                MaintenanceCustomerId = customerAddressesSource.LastModificationPerson.IDs[0].Value,
                MaintenanceUser = customerAddressesSource.LastModificationPerson.Name.Value,
                MaintenanceDate = DateTime.UtcNow
            };
        }
 }

这就是我注册它的方式:

Mapper.CreateMap<SyncBillToPartyMaster, CustomerAddress>().ConvertUsing(new CustomerAddressBillToPartyMasterMapper());

我认为这比我之前发布的代码干净多了。