Visual Studio 可视化工具:第 3 部分 - 集合可视化工具





5.00/5 (5投票s)
该项目为 .NET 集合创建 Visual Studio 可视化工具
介绍
该项目为 .NET 列表集合创建 Visual Studio 可视化工具:List<T>
。
项目网站:http://vsdatawatchers.codeplex.com。
背景
第 1 部分在此处提供:https://codeproject.org.cn/Articles/578777/Visual-Studio-Visualizer-Part-1
如果您不熟悉 Visual Studio 可视化工具,我建议阅读第 1 部分。
第 2 部分在此处提供:https://codeproject.org.cn/Articles/584739/Visual-Studio-Visualizer-Part-2-Entity-Framework。
使用代码
关于 List<> 的反射
为了将列表中的值读取到可视化工具中,使用了简单的 DTO
[Serializable]
public class Entity
{
public Guid Pk = Guid.NewGuid();
public string Name { get; set; }
List<EntityProperties> properties;
public List<EntityProperties> Properties
{
get
{
if (properties == null)
properties = new List<EntityProperties>();
return properties;
}
set { properties = value; }
}
List<Entity> nestedEntities;
public List<Entity> NestedEntities
{
get
{
if (nestedEntities == null)
nestedEntities = new List<Entity>();
return nestedEntities;
}
set { nestedEntities = value; }
}
}
此类包含一个名称、一个属性列表以及一个名为 NestedEntities
的其他复杂属性列表。
EntityProperties
是用于简单的 .NET 属性(如字符串、整数等)的容器
[Serializable]
public class EntityProperties
{
public string PropertyName { get; set; }
public object Value { get; set; }
public string PropertyType { get; set; }
}
反射方法遍历列表中的所有条目,并填充一个 List<Entity>
,然后将其传递给可视化工具
private void WriteObject(object o, Entity currentEntity)
{
if (o is IEnumerable)
{
foreach (object element in (IEnumerable)o)
{
if (element is IEnumerable && !(element is string))
{
if (level < depth)
{
level++;
WriteObject(element, currentEntity);
level--;
}
}
else
WriteObject(element, currentEntity);
}
}
else
{
//reads the object members
MemberInfo[] members = o.GetType().GetMembers(
BindingFlags.Public | BindingFlags.Instance);
Entity newEntity = new Entity();
newEntity.Name = o.ToString();
//we are only interested in properties and fields
foreach (MemberInfo m in members.Where(p => p is FieldInfo || p is PropertyInfo))
{
FieldInfo f = m as FieldInfo;
PropertyInfo p = m as PropertyInfo;
if (f != null || p != null)
{
Type t = f != null ? f.FieldType : p.PropertyType;
//reads the properties values, name value and type
EntityProperties property = new EntityProperties();
property.PropertyName = m.Name;
property.PropertyType = t.FullName;
if (t.IsValueType || t == typeof(string))
{
try
{
//reads the value
property.Value = f != null ? f.GetValue(o) : p.GetValue(o, null);
newEntity.Properties.Add(property);
}
catch { }
}
}
}
//add to new entity or as a nested entity
if (currentEntity == null)
entities.Add(newEntity);
else
currentEntity.NestedEntities.Add(newEntity);
//where we read the complex properties until the defined depth
if (level < depth)
{
foreach (MemberInfo m in members.Where(p => p is FieldInfo || p is PropertyInfo))
{
FieldInfo f = m as FieldInfo;
PropertyInfo p = m as PropertyInfo;
if (f != null || p != null)
{
Type t = f != null ? f.FieldType : p.PropertyType;
if (!(t.IsValueType || t == typeof(string)))
{
try
{
object value = f != null ? f.GetValue(o) : p.GetValue(o, null);
if (value != null)
{
level++;
WriteObject(value, newEntity);
level--;
}
}
catch { }
}
}
}
}
}
}
对于可视化的列表中的每个条目,都使用递归,就像对于每个复杂的关联实体一样。
此版本仅支持 List<>
的可视化,但考虑到未来的版本,创建了一个扩展方法
public static List<Entity> DumpMe(this Object o, int depth = 2)
{
string filename = System.IO.Path.Combine(Environment.GetFolderPath(
Environment.SpecialFolder.ApplicationData),
"CodeVisualizer", "CodeVisualizerOptions.xml");
if (File.Exists(filename))
{
XDocument doc = XDocument.Load(filename);
XElement xe = doc.Descendants("Depth").FirstOrDefault();
if (xe != null)
int.TryParse(xe.Value, out depth);
}
return Dump.ReadObject(o, depth).entities;
}
Dump.ReadObject
只是调用了描述的方法。这里使用 XDocument 来读取深度,此值可以由用户在可视化工具中持久化。将此值存储在属性项目中不起作用,返回的值始终为 0,并且使用 XmlSerializer
读取文件也返回 0,因此 XDocument
是一个解决方法。
使用可视化工具
在 第 1 部分 中,详细解释了如何使用可视化工具。
可视化工具以树状视图显示信息,所有复杂属性都作为子节点。呈现的信息是属性的名称、其值和 Type
。
可以过滤信息,这在包含大量项目的列表中至关重要。可以通过名称、值或类型进行过滤
可以更改深度,即显示的复杂属性(子项)。出于性能原因,存在此限制,测试是使用实体框架进行的,如果不使用深度限制,可视化工具可以一次检索所有数据库,一个属性一个属性!!! 要更改使用的深度,请更改深度文本框中的值并重新启动可视化工具。
对于更详细的操作,可以将数据导出到 XML 和 Excel
导出到 Excel 文件保留了树状层次结构
此第一个版本 v20130601 不允许更改值,将在下一个版本中实现。
历史
- 2013-06-03:文章创建。