Abp.DataDictionary
Abp.DataDictionary copied to clipboard
能否支持自动渲染复杂对象
很常见地,数据对象会有一些非简单类型的成员、列表等也可能含有需要渲染的字典字段。 以目前的方式,只能逐个去手动处理,在试着手动渲染了几处之后,发现非常的麻烦且冗余。
希望能加上自动渲染复杂对象的功能。
我尝试自己扩展,临时实现了一下,方式可能不是太好,供参考。
加了一个特性:DictionaryChildFieldAttribute
,用来标记需要进一步渲染的字段。
扩展了DataDictionaryLoader
的ScanRules
方法:
把标记了DictionaryChildField
的字段记录下来,并且判断一下是否是IEnumerable
,也记录下来
这里借用了 DataDictionaryRule
,临时用自己的方式保存了规则信息
var properties = type
.GetProperties()
.Where(p => p.IsDefined(typeof(DictionaryChildFieldAttribute)))
.ToList();
rules.AddRange(properties.Select(property => new DataDictionaryRule
{
DictionaryCode = property.PropertyType.IsAssignableTo(typeof(IEnumerable)) ? "IEnumerable" : "",
DtoType = type,
RenderFieldProperty = property,
DictionaryCodeProperty = null
}));
在需要的字段加上这个特性作为标记:
public class PlanDto {
[DictionaryCodeField(“Category")]
public string Category { get; set; }
[DictionaryRenderField(“Category")]
public string CategoryName { get; set; }
[DictionaryChildField]
public List<TeamDto> Teams {get;set;}
[DictionaryChildField]
public User Manager {get;set;}
}
扩展了一个非泛型的Render方法,将 Type 作为参数传入: Task RenderAsync(object sourceDto, Type dtoType)
渲染时,增加了对”新规则“的处理:
if (rule.DictionaryCodeProperty == null)
{
var childDto = rule.RenderFieldProperty.GetValue(sourceDto);
if (rule.DictionaryCode == "IEnumerable" && childDto != null)
{
var type = rule.RenderFieldProperty.PropertyType.GenericTypeArguments.FirstOrDefault();
foreach (var item in (IEnumerable) childDto)
{
await RenderAsync(item, type);
}
}
else
{
await RenderAsync(childDto, rule.RenderFieldProperty.PropertyType);
}
continue;
}
目前使用暂无问题,但还是希望用上原生功能