public ClientSideTypeDescription RegisterTypeIfNeeded(Type type, TypeDescriptionConfig description) { ClientSideTypeDescription result = null; foreach (var client in CacheClients) { result = client.RegisterTypeIfNeeded(type, description); } return(result); }
/// <summary> /// Register a type as cacheable with an external description /// Cacheable type descriptions can be provided by attributes on the public properties /// or as <see cref="TypeDescriptionConfig" />. /// If an external description is required, the type must be explicitly registered. /// </summary> /// <param name="type"></param> /// <param name="description"></param> public ClientSideTypeDescription RegisterTypeIfNeeded(Type type, TypeDescriptionConfig description) { if (KnownTypes.TryGetValue(description.FullTypeName, out var typeDescription)) { return(typeDescription); } typeDescription = ClientSideTypeDescription.RegisterType(type, description); KnownTypes[typeDescription.FullTypeName] = typeDescription; var request = new RegisterTypeRequest(typeDescription.AsTypeDescription, ShardIndex, ShardsCount); var response = Channel.SendRequest(request); if (response is ExceptionResponse exResponse) { throw new CacheException("Error while registering a type on the server", exResponse.Message, exResponse.CallStack); } return(typeDescription); }
/// <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); }