[英]How to map a somewhat complex architecture with automapper and constructUsing
I have the following situation which I cannot get mapped properly: 我遇到以下情况,无法正确映射:
I receive a list of following objects from a call to the camunda api. 我从对camunda api的调用中收到以下对象的列表。
public class CamundaTask
{
public string FormKey { get; set; }
public string Id { get; set; }
public string Name { get; set; }
...
}
And I would like to map it to specific tasks in my code ( ContactUpdateTask
or OrganisationAquisitionTask
) depending on the formkey. 我想根据formkey将其映射到我的代码中的特定任务(
ContactUpdateTask
或OrganisationAquisitionTask
)。
Following is my architecture: 以下是我的体系结构:
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"; }
}
I know how to deal with simple inheritance and automapper but the whole TContext throws me off a little. 我知道如何处理简单的继承和自动映射器,但是整个TContext使我有点失望。 This is what I have so far but it produces following error: "Mapper not initialized. Call Initialize with appropriate configuration."
到目前为止,这是我所拥有的,但是会产生以下错误:“映射器未初始化。使用适当的配置调用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());
I map with the following line of code: 我使用以下代码行进行映射:
var tasks = _mapper.Map<IEnumerable<BaseTask>>(camundaTasks)
Where camundaTasks
is of type IEnumerable<CamundaTask>
其中
camundaTasks
的类型为IEnumerable<CamundaTask>
What is the proper way to do the mapping so that my tasks list contains objects of ContactUpdateTask
or OrganisationAquisitionTask
depending on the formkey of the CamundaTask
? 进行映射以使我的任务列表包含
ContactUpdateTask
或OrganisationAquisitionTask
对象的正确方法是什么,具体取决于CamundaTask的CamundaTask
?
So what happens here is that you initialize Automapper in a non-static way (isn't clear from your original post, but I could deduct that because my comment seemed to have solved your problem), but you are using Automapper statically within the ConstructUsing method. 因此,这里发生的是您以一种非静态的方式初始化了Automapper(从您的原始帖子中还不清楚,但是我可以推断出这一点,因为我的评论似乎已经解决了您的问题),但是您在ConstructUsing中静态地使用了Automapper方法。
There's two solutions for this: 有两种解决方案:
1) Use Automapper statically 1)静态使用Automapper
Mapper.Initialize(cfg=> cfg.CreateMap<CamundaTask, BaseTask>());
2) Use ResolutionContext 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.