using Autodesk.Revit.DB; using Autodesk.Revit.DB.ExtensibleStorage; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace FWindSoft.Revit.ExtensibleStorage { /* * 可能只能存储,几个kb的值 * 1、Schema需要一次创建,创建完成之后不能再进行修改 * 2、api可用性很高,暂时简单封装 */ public static class ExtensibleStorageExtension { #region 基础扩展数据操作 public static void SetExtendData(this Element element, SchemaItem schemaItem, T value) { var guid = schemaItem.SchemaGuid; var schemaName = schemaItem.SchemaName; var fileName = schemaItem.FileName; Schema schema = Schema.Lookup(guid); if (schema == null) { SchemaBuilder schemaBuilder = new SchemaBuilder(guid); schemaBuilder.SetReadAccessLevel(AccessLevel.Public); schemaBuilder.SetWriteAccessLevel(AccessLevel.Public); //这个应该和上面重复吧 schemaBuilder.SetSchemaName(schemaName); FieldBuilder fieldBuilder = schemaBuilder.AddSimpleField(fileName, typeof(T)); schema = schemaBuilder.Finish(); } Entity entity = new Entity(schema); Field field = schema.GetField(fileName); entity.Set(field, value); element.SetEntity(entity); } public static void SetExtendData(this Element element, SchemaItem schemaItem, IList values) { var guid = schemaItem.SchemaGuid; var schemaName = schemaItem.SchemaName; var fileName = schemaItem.FileName; Schema schema = Schema.Lookup(guid); if (schema == null) { SchemaBuilder schemaBuilder = new SchemaBuilder(guid); schemaBuilder.SetReadAccessLevel(AccessLevel.Public); schemaBuilder.SetWriteAccessLevel(AccessLevel.Public); schemaBuilder.SetSchemaName(schemaName); FieldBuilder fieldBuilder = schemaBuilder.AddArrayField(fileName, typeof(T)); schema = schemaBuilder.Finish(); } Entity entity = new Entity(schema); Field field = schema.GetField(fileName); entity.Set>(field, values); element.SetEntity(entity); } public static void SetExtendData(this Element element, SchemaItem schemaItem, IDictionary dict) { var guid = schemaItem.SchemaGuid; var schemaName = schemaItem.SchemaName; var fileName = schemaItem.FileName; Schema schema = Schema.Lookup(guid); if (schema == null) { SchemaBuilder schemaBuilder = new SchemaBuilder(guid); schemaBuilder.SetReadAccessLevel(AccessLevel.Public); schemaBuilder.SetWriteAccessLevel(AccessLevel.Public); schemaBuilder.SetSchemaName(schemaName); FieldBuilder fieldBuilder = schemaBuilder.AddMapField(fileName, typeof(T), typeof(V)); schema = schemaBuilder.Finish(); } Entity entity = new Entity(schema); Field field = schema.GetField(fileName); entity.Set>(field, dict); element.SetEntity(entity); } public static T GetExtendData(this Element element, SchemaItem schemaItem) { var guid = schemaItem.SchemaGuid; var schemaName = schemaItem.SchemaName; var fileName = schemaItem.FileName; Schema schema = Schema.Lookup(guid); if (schema != null) { Entity entity = element.GetEntity(schema); if (entity.Schema == null) { return default(T); } Field field = schema.GetField(fileName); if (!entity.RecognizedField(field)) { return default(T); } return entity.Get(field); } return default(T); } public static List GetExtendDatas(this Element element, SchemaItem schemaItem) { var guid = schemaItem.SchemaGuid; var fileName = schemaItem.FileName; Schema schema = Schema.Lookup(guid); if (schema != null) { Entity entity = element.GetEntity(schema); Field field = schema.GetField(fileName); return entity.Get>(field).ToList(); } return null; } public static Dictionary GetExtendData(this Element element, SchemaItem schemaItem) { var guid = schemaItem.SchemaGuid; var schemaName = schemaItem.SchemaName; var fileName = schemaItem.FileName; Schema schema = Schema.Lookup(guid); if (schema != null) { Entity entity = element.GetEntity(schema); Field field = schema.GetField(fileName); return entity.Get>(field) as Dictionary; } return null; } #endregion /// /// 删除扩展数据 /// /// /// public static void DeleteStorageData(this Element element, Guid guid) { Schema schema = Schema.Lookup(guid); if (schema != null) { element.DeleteEntity(schema); } } /// /// 存储简单对象数据 /// /// /// /// public static void SetSimpleClass(this Element element, T value) { var useType = typeof(T); Guid guid = useType.GUID; Schema schema = Schema.Lookup(guid); #region 初始化属性集合 List> useProperties = new List>(); if (ExtensibleStorageUtil.IsCoustomStorage(useType)) { var useValue = ((ICoustomStorage)value).GetStorage(); var propertyType = useValue.GetType(); useProperties.Add(new Tuple(useType.Name, propertyType, useValue)); } else { var properties = useType.GetProperties(); foreach (var propertyInfo in properties) { var propertyType = propertyInfo.PropertyType; var useValue = propertyInfo.GetValue(value); useProperties.Add(new Tuple(propertyInfo.Name, propertyType, useValue)); } } #endregion #region 创建结构 if (schema == null) { #region 创建Schema SchemaBuilder schemaBuilder = new SchemaBuilder(guid); schemaBuilder.SetReadAccessLevel(AccessLevel.Public); schemaBuilder.SetWriteAccessLevel(AccessLevel.Public); schemaBuilder.SetSchemaName(useType.Name); #endregion foreach (var item in useProperties) { var propertyType = item.Item2; if (ExtensibleStorageUtil.IsEffectiveContent(propertyType)) { FieldBuilder fieldBuilder = schemaBuilder.AddSimpleField(item.Item1, propertyType); } else if (ExtensibleStorageUtil.IsEffectiveArray(propertyType, out Type arryContentType)) { FieldBuilder fieldBuilder = schemaBuilder.AddArrayField(item.Item1, arryContentType); } else if (ExtensibleStorageUtil.IsEffectiveMap(propertyType, out Type keyType, out Type valueType)) { FieldBuilder fieldBuilder = schemaBuilder.AddMapField(item.Item1, keyType, valueType); } } schema = schemaBuilder.Finish(); } #endregion #region 创建对象 Entity entity = new Entity(schema); var method = ExtensibleStorageUtil.GetEntitySetMethod(); foreach (var item in useProperties) { var field = schema.GetField(item.Item1); if (field == null) continue; var fieldType = ExtensibleStorageUtil.GetFileType(field); MethodInfo mi = method.MakeGenericMethod(fieldType); var useValue = item.Item3; if (useValue != null) { mi.Invoke(entity, new object[] { item.Item1, useValue }); } } #endregion element.SetEntity(entity); } /// /// 获取简单对象数据 /// /// /// public static T GetSimpleClass(this Element element) { var useType = typeof(T); Guid guid = useType.GUID; Schema schema = Schema.Lookup(guid); if (schema == null) { return default(T); } Entity entity = element.GetEntity(schema); if (entity?.Schema == null) { return default(T); } var fields = schema.ListFields(); #region 创建实体对象 T result = default(T); if (fields.Any()) { var cons = useType.GetConstructor(Type.EmptyTypes); if (cons != null) { result = (T)cons.Invoke(null); } } if (result == null) { return default(T); } #endregion var getMethod = typeof(Entity).GetMethod("Get", new Type[] { typeof(string) }); if (ExtensibleStorageUtil.IsCoustomStorage(useType)) { var field = fields.FirstOrDefault(f => f.FieldName == useType.Name); if (field != null) { var useValueType = field.ValueType; if (field.ContainerType == ContainerType.Array) { useValueType = typeof(IList<>).MakeGenericType(field.ValueType); } else if (field.ContainerType == ContainerType.Map) { useValueType = typeof(IDictionary<,>).MakeGenericType(field.KeyType, field.ValueType); } MethodInfo mi = getMethod.MakeGenericMethod(useValueType); var useValue = mi.Invoke(entity, new object[] { field.FieldName }); ((ICoustomStorage)result).SetStorage(useValue); } } else { foreach (var field in fields) { try { var property = useType.GetProperty(field.FieldName); if (property != null) { MethodInfo mi = getMethod.MakeGenericMethod(property.PropertyType); var useValue = mi.Invoke(entity, new object[] { field.FieldName }); property.SetValue(result, useValue); } } catch (Exception) { } } } return result; } } public class SchemaItem { public Guid SchemaGuid { get; set; } public string SchemaName { get; set; } public string FileName { get; set; } } }