Example #1
0
        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);
        }