Пример #1
0
        public static void EnsureHasAllTypeCache(Type type, SaveInheritanceAttribute info)
        {
            lock (info)
            {
                // Just use one of them to see if the cache is valid or not.
                if (info.HasGeneratedFullKeyCache)
                {
                    return;
                }

                KeyedSubTypeInfo[]? keyedInfo = GetKeyedSubTypesFor(type);

                // We'll also fill in the serialize cache since we've now gone through all the types.
                info.KeySerializeCache   = new Dictionary <Type, string>(keyedInfo.Length);
                info.KeyDeserializeCache = new Dictionary <string, Type>(keyedInfo.Length);

                for (int i = 0; i < keyedInfo.Length; i++)
                {
                    KeyedSubTypeInfo currentInfo = keyedInfo[i];

                    info.KeySerializeCache.Add(currentInfo.Type, currentInfo.Key);
                    info.KeyDeserializeCache.Add(currentInfo.Key, currentInfo.Type);
                }

                info.HasGeneratedFullKeyCache = true;
            }
        }
Пример #2
0
        static KeyedSubTypeInfo[] GetKeyedSubTypesFor(Type type)
        {
            AssemblyName?typeAssemblyName = type.Assembly.GetName();

            Assembly[]? currentAssemblies = AppDomain.CurrentDomain.GetAssemblies();

            var res = new List <KeyedSubTypeInfo>();

            for (int i = 0; i < currentAssemblies.Length; i++)
            {
                AssemblyName[]? referenced = currentAssemblies[i].GetReferencedAssemblies();

                if (currentAssemblies[i] == type.Assembly)
                {
                    goto Accept;
                }

                for (int j = 0; j < referenced.Length; j++)
                {
                    if (referenced[j].Name == typeAssemblyName.Name)
                    {
                        goto Accept;
                    }
                }

                continue;

                Accept:
                {
                    Type[]? subTypes = currentAssemblies[i].GetTypes();

                    Parallel.ForEach(subTypes, t =>
                    {
                        if (!t.IsSubclassOf(type))
                        {
                            return;
                        }

                        SaveInheritanceKeyAttribute?attribute = t.GetCustomAttribute <SaveInheritanceKeyAttribute>(false);
                        if (attribute == null)
                        {
                            return;
                        }

                        var newInfo = new KeyedSubTypeInfo(t, attribute.Key);

                        // Since it's EXTREMELY unlikely a type will be a sub-class (say 5 / 1000 types),
                        // we don't mind the synchronization as it should be very uncommon.
                        lock (res)
                            res.Add(newInfo);
                    });
                }
            }

            return(res.ToArray());
        }