簡體   English   中英

如何使用自動映射器和Constructor映射稍微復雜的體系結構

[英]How to map a somewhat complex architecture with automapper and constructUsing

我遇到以下情況,無法正確映射:

我從對camunda api的調用中收到以下對象的列表。

public class CamundaTask
{
    public string FormKey { get; set; }
    public string Id { get; set; }
    public string Name { get; set; }
    ...
}  

我想根據formkey將其映射到我的代碼中的特定任務( ContactUpdateTaskOrganisationAquisitionTask )。

以下是我的體系結構:

public class BaseTask
{
    public virtual string TaskType { get; set; }
    public string Id { get; set; }
    public int Priority { get; set; }
    public string Key { get; set; }
    ...
}

public abstract class ProcessTask<TContext> : BaseTask
{
    public TContext TaskContext { get; set; }
}

public class ContactUpdateContext
{
    public Guid PersonId { get; set; }
    public string FullName { get; set; }
}

public class OrganisationAquisitionContext
{
    public Guid OrganisationId { get; set; }
    public string Name { get; set; }
}

public class ContactUpdateTask : ProcessTask<ContactUpdateContext>
{
    public override string TaskType { get => "UpdateContact"; }
}

public class OrganisationAquisitionTask : ProcessTask<OrganisationAquisitionContext>
{
    public override string TaskType { get => "OrganisationAquisition"; } 
}

我知道如何處理簡單的繼承和自動映射器,但是整個TContext使我有點失望。 到目前為止,這是我所擁有的,但是會產生以下錯誤:“映射器未初始化。使用適當的配置調用Initialize。”

CreateMap<ContactUpdateTask, ProcessTask<ContactUpdateContext>>().ReverseMap();
CreateMap<ContactValidationTask, ProcessTask<OrganisationAquisitionTask>>().ReverseMap();
CreateMap<OrganisationAquisitionTask, ProcessTask<ContactValidationTask>>().ReverseMap();

CreateMap<BaseTask, CamundaTask>()
   .ForMember(t => t.FormKey, opt => opt.MapFrom(p => p.TaskType))
   .ForMember(t => t.Assignee, opt => opt.MapFrom(p => p.Owner))
   .ForMember(t => t.Id, opt => opt.MapFrom(p => p.Key))
   .ForAllOtherMembers(opt => opt.Ignore());

CreateMap<CamundaTask, ContactUpdateTask>()
    .ForMember(t => t.TaskType, opt => opt.MapFrom(p => p.FormKey))
    .ForMember(t => t.Owner, opt => opt.MapFrom(p => p.Assignee))
    .ForMember(t => t.Key, opt => opt.MapFrom(p => p.Id))
    .ForAllOtherMembers(opt => opt.Ignore());

CreateMap<CamundaTask, ContactValidationTask>()
    .ForMember(t => t.TaskType, opt => opt.MapFrom(p => p.FormKey))
    .ForMember(t => t.Owner, opt => opt.MapFrom(p => p.Assignee))
    .ForMember(t => t.Key, opt => opt.MapFrom(p => p.Id))
    .ForAllOtherMembers(opt => opt.Ignore());

CreateMap<CamundaTask, OrganisationAquisitionTask>()
    .ForMember(t => t.TaskType, opt => opt.MapFrom(p => p.FormKey))
    .ForMember(t => t.Owner, opt => opt.MapFrom(p => p.Assignee))
    .ForMember(t => t.Key, opt => opt.MapFrom(p => p.Id))
    .ForAllOtherMembers(opt => opt.Ignore());

CreateMap<CamundaTask, BaseTask>()
    .ConstructUsing((CamundaTask task) =>
    {
        switch (task.FormKey.ToLower())
        {
            case "updateorganization":
                return Mapper.Map<ContactUpdateTask>(task);
            case "contactValidation":
                return Mapper.Map<ContactValidationTask>(task);
            case "organizationacquisition":
                return Mapper.Map<OrganisationAquisitionTask>(task);       
        }

        return Mapper.Map<BaseTask>(task);
    })
   .ForMember(t => t.TaskType, opt => opt.MapFrom(p => p.FormKey))
   .ForMember(t => t.Owner, opt => opt.MapFrom(p => p.Assignee))
   .ForMember(t => t.Key, opt => opt.MapFrom(p => p.Id))
   .ForAllOtherMembers(opt => opt.Ignore());

我使用以下代碼行進行映射:

var tasks = _mapper.Map<IEnumerable<BaseTask>>(camundaTasks)

其中camundaTasks的類型為IEnumerable<CamundaTask>

進行映射以使我的任務列表包含ContactUpdateTaskOrganisationAquisitionTask對象的正確方法是什么,具體取決於CamundaTask的CamundaTask

因此,這里發生的是您以一種非靜態的方式初始化了Automapper(從您的原始帖子中還不清楚,但是我可以推斷出這一點,因為我的評論似乎已經解決了您的問題),但是您在ConstructUsing中靜態地使用了Automapper方法。

有兩種解決方案:

1)靜態使用Automapper

Mapper.Initialize(cfg=> cfg.CreateMap<CamundaTask, BaseTask>());

2)使用ResolutionContext

.ConstructUsing((CamundaTask task, ResolutionContext context) =>
{
    switch (task.FormKey.ToLower())
    {
        case "updateorganization":
            return context.Mapper.Map<ContactUpdateTask>(task);
        case "contactValidation":
            return context.Mapper.Map<ContactValidationTask>(task);
        case "organizationacquisition":
            return context.Mapper.Map<OrganisationAquisitionTask>(task);       
    }

    return context.Mapper.Map<BaseTask>(task);
})

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM