/// <summary> /// Factory method used to create a precompiled type description. /// This version of the method uses an external description (no need to attach attributes to the public properties) /// In order to be cacheable, a type must be serializable and must have exactly one primary key /// Optionally it can have multiple unique keys and index keys /// </summary> /// <param name="type"> </param> /// <param name="typeDescription"> </param> /// <returns> </returns> public static ClientSideTypeDescription RegisterType(Type type, TypeDescriptionConfig typeDescription) { if (type == null) { throw new ArgumentNullException(nameof(type)); } if (!type.IsSerializable) { throw new NotSupportedException( $"the type {type} is not serializable so it can not be registered as cacheable type"); } var result = new ClientSideTypeDescription { TypeName = type.Name, FullTypeName = type.FullName, UseCompression = typeDescription.UseCompression }; var props = type.GetProperties(); foreach (var info in props) { if (typeDescription.Keys.ContainsKey(info.Name)) { var propertyDescription = typeDescription.Keys[info.Name]; result._propertyDescriptionByName[info.Name] = propertyDescription; var key = new ClientSideKeyInfo(info, propertyDescription); if (key.KeyType == KeyType.None) { continue; } if (key.KeyType == KeyType.Primary) { result.PrimaryKeyField = key; } else if (key.KeyType == KeyType.Unique) { result._uniqueKeyFields.Add(key); } else if (key.KeyType == KeyType.ScalarIndex) { result._indexFields.Add(key); } else if (key.KeyType == KeyType.ListIndex) { result._listFields.Add(key); } } } //check if the newly registered type is valid if (result.PrimaryKeyField == null) { throw new NotSupportedException($"no primary key defined for type {type}"); } return(result); }
/// <summary> /// Factory method used to create a precompiled type description. /// This version of the method uses a tagged type ( Attributes are attached to the public properties /// which are indexed in the cache) /// In order to be cacheable, a type must be serializable and must have exactly one primary key /// Optionally it can have multiple unique keys and index keys /// </summary> /// <param name="type"> type to register (must be properly decorated) </param> /// <returns> not null type description if successful </returns> public static ClientSideTypeDescription RegisterType(Type type) { if (type == null) { throw new ArgumentNullException(nameof(type)); } var useCompression = false; var storage = type.GetCustomAttributes(typeof(StorageAttribute), false).FirstOrDefault(); if (storage != null) { var storageParams = (StorageAttribute)storage; useCompression = storageParams.UseCompression; } var result = new ClientSideTypeDescription { UseCompression = useCompression, TypeName = type.Name, FullTypeName = type.FullName }; var props = type.GetProperties(); foreach (var info in props) { var key = new ClientSideKeyInfo(info); if (key.KeyType == KeyType.None) { continue; } if (key.KeyType == KeyType.Primary) { result.PrimaryKeyField = key; } else if (key.KeyType == KeyType.Unique) { result._uniqueKeyFields.Add(key); } else if (key.KeyType == KeyType.ScalarIndex) { result._indexFields.Add(key); } else if (key.KeyType == KeyType.ListIndex) { result._listFields.Add(key); } var propertyDescription = new PropertyDescription { PropertyName = key.Name, KeyDataType = key.KeyDataType, KeyType = key.KeyType, Ordered = key.IsOrdered }; result._propertyDescriptionByName[key.Name] = propertyDescription; } //check if the newly registered type is valid if (result.PrimaryKeyField == null) { throw new NotSupportedException($"No primary key defined for type {type}"); } return(result); }