我有一个行为类TaskBehavior,它有一个参数构造函数,可以驱动表单中属性的可见性,同时也可以驱动应该映射到数据库实体的属性。 其次,我有一个DTO类TaskDto,最后是一个数据库实体Task:
public class TaskDto
{
public string Name { get; set; }
public string Description { get; set; }
}
public class Task
{
public string Name { get; set; }
public string Description { get; set; }
}
public class TaskBehavior
{
public TaskBehavior(bool secure)
{
NameVisible = true;
DescriptionVisible = secure;
}
public bool NameVisible { get; private set; }
public bool DescriptionVisible { get; private set; }
}
我需要将TaskDto中的属性映射到Task,但只需要由TaskBehavior决定的属性。目的是只使用一个参数化规则集来指导可见性和条件映射:
void SaveData(TaskDto taskDto)
{
var behavior = new TaskBehavior(false);
var entity = Mapper.Map<Task>(taskDto); // TODO: only map properties based on "behavior" definition
}
结果应该是在这种情况下只有Name属性从taskDto映射到实体(根据行为实例)。
答案 0 :(得分:0)
最后我让它自己工作了。我们的想法是使用ad-hoc创建的MappingEngine实例和基于SOME参数的动态创建的映射。整个魔术在TaskMappingEngineFactory类中,它还将创建的MappingEngine-s缓存到静态集合中以提高性能。
public static class TaskMappingEngineFactory
{
private static readonly object _lock = new object();
private static Dictionary<Enums.PortalEnum, MappingEngine> _mappingEngines = new Dictionary<Enums.PortalEnum, MappingEngine>();
public static MappingEngine GetMappingEngine(TaskBehavior taskBehavior)
{
lock (_lock)
{
MappingEngine mappingEngine;
if (!_mappingEngines.TryGetValue(taskBehavior.PortalType, out mappingEngine))
{
ConfigurationStore store = new ConfigurationStore(new TypeMapFactory(), MapperRegistry.Mappers);
store.CreateMap<TaskInfoDetail, TaskInfoDetail>()
.ForMember(dst => dst.CanExecuteAutomatically, o => o.Condition((Func<TaskInfoDetail,bool>)(src => taskBehavior.AdvancedPropertiesVisible)))
.ForMember(dst => dst.CanExecuteManually, o => o.Condition((Func<TaskInfoDetail,bool>)(src => taskBehavior.AdvancedPropertiesVisible)));
MappingEngine engine = new MappingEngine(store);
_mappingEngines.Add(taskBehavior.PortalType, mappingEngine = engine);
}
return mappingEngine;
}
}
}
在“更新”方法中,我只需添加一行来创建引擎实例 工厂。非常简单,非常简单,不那么软化,但现在已足够了;)
var behavior = new TaskBehavior(NopContext.Current.PortalType());
var engine = TaskMappingEngineFactory.GetMappingEngine(behavior);
engine.Map(task, updatedTask);