示例#1
0
 /// <summary>
 /// Add an item to cache if it is not already in it
 /// </summary>
 /// <param name="info">Item to add</param>
 /// <param name="keyName">The key name of the object</param>
 public static void TrySet(ClassInformation info, string keyName)
 {
     lock (cacheAccessLock)
     {
         if (!cache.ContainsKey(keyName))
         {
             cache.Add(keyName, info);
         }
     }
 }
示例#2
0
        /// <summary>
        /// Inspect a class for Azure Tables
        /// </summary>
        /// <typeparam name="ClassT">Type of business class to be stored into Azure Tables</typeparam>
        /// <returns>Reflected class metadata</returns>
        public static ClassInformation?InspectForAzureTables <ClassT>()
            where ClassT : class
        {
            Type             classType      = typeof(ClassT);
            string           cacheKeyName   = classType.FullName ?? classType.Name;
            ClassInformation?objectMetadata = Cache.TryGet(cacheKeyName);

            if (objectMetadata != null)
            {
                // cache hit
                return(objectMetadata);
            }

            TableAttribute?tableAttribute = classType.GetCustomAttribute <TableAttribute>(true);

            if (tableAttribute == null)
            {
                return(null);
            }

            List <Property> properties = new List <Property>();
            List <Field>    fields     = new List <Field>();

            bool hasPartitionKey = false, hasRowKey = false, hasETag = false, hasTimestamp = false;

            foreach (MemberInfo member in classType.GetMembers(MEMBER_SEARCH_FLAGS))
            {
                object[] memberAttributes = member.GetCustomAttributes(true);
                if ((memberAttributes == null) || (memberAttributes.Length == 0))
                {
                    continue;
                }

                foreach (object attribute in memberAttributes)
                {
                    if (attribute is ETagAttribute)
                    {
                        if (hasETag)
                        {
                            throw new InvalidOperationException($"'{cacheKeyName}' has multiple ETag properties defined.");
                        }

                        hasETag = true;
                    }

                    if (attribute is PartitionKeyAttribute)
                    {
                        if (hasPartitionKey)
                        {
                            throw new InvalidOperationException($"'{cacheKeyName}' has multiple PartitionKey properties defined.");
                        }

                        hasPartitionKey = true;
                    }

                    if (attribute is RowKeyAttribute)
                    {
                        if (hasRowKey)
                        {
                            throw new InvalidOperationException($"'{cacheKeyName}' has multiple RowKey properties defined.");
                        }

                        hasRowKey = true;
                    }

                    if (attribute is TimestampAttribute)
                    {
                        // since we never read this back into the TableEntity, there can be as many of these as the developer wants :)
                        hasTimestamp = true;
                    }
                }

                if (!(hasPartitionKey || hasRowKey))
                {
                    continue;
                }

                switch (member.MemberType)
                {
                case MemberTypes.Field:
                    FieldInfo?fi = member as FieldInfo;
                    if (fi != null)
                    {
                        fields.Add(new Field(fi));
                    }
                    break;

                case MemberTypes.Property:
                    PropertyInfo?pi = member as PropertyInfo;
                    if (pi != null)
                    {
                        properties.Add(new Property(pi));
                    }
                    break;
                }
            }

            if ((properties.Count == 0) && (fields.Count == 0) || (!hasPartitionKey) || (!hasRowKey))
            {
                return(null);
            }

            objectMetadata = new ClassInformation(classType.Name, cacheKeyName, tableAttribute, properties, fields)
            {
                // without these two, we don't get here!
                HasPartitionKey = true,
                HasRowKey       = true,

                HasETag      = hasETag,
                HasTimestamp = hasTimestamp
            };


            Cache.TrySet(objectMetadata, cacheKeyName);

            return(objectMetadata);
        }