static AssemblyName GetAssemblyName(Assembly assembly)
        {
            object key = assembly.IsDynamic ? (object)new WeakRefKey(assembly) : assembly;

            lock (syncObject)
            {
                AssemblyName result;
                if (_assemblies == null)
                {
                    _assemblies = new Dictionary <object, AssemblyName>();
                }
                else
                {
                    if (_assemblies.TryGetValue(key, out result))
                    {
                        return(result);
                    }
                }
                //
                // We use AssemblyName ctor here because GetName demands FileIOPermission
                // and does load more than just the required information.
                // Essentially we use AssemblyName just to help parsing the name, version, culture
                // and public key token from the assembly's name.
                //
                result = new AssemblyName(assembly.FullName);
                _assemblies.Add(key, result);
                if (assembly.IsDynamic && !_isGCCallbackPending)
                {
                    // Make sure we clean up the cache if/when this dynamic assembly is GCed
                    GCNotificationToken.RegisterCallback(_cleanupCollectedAssemblies, null);
                    _isGCCallbackPending = true;
                }
                return(result);
            }
        }
        // After a GC, clean up the weakrefs to any collected dynamic assemblies
        static void CleanupCollectedAssemblies(object state) // dummy parameter required by WaitCallback definition
        {
            bool          foundLiveDynamicAssemblies = false;
            List <object> keysToRemove = null;

            lock (syncObject)
            {
                foreach (object key in _assemblies.Keys)
                {
                    WeakReference weakRef = key as WeakReference;
                    if (weakRef == null)
                    {
                        continue;
                    }
                    if (weakRef.IsAlive)
                    {
                        // There is a weak ref that is still alive, register another GC callback for next time
                        foundLiveDynamicAssemblies = true;
                    }
                    else
                    {
                        // The target has been collected, add it to our list of keys to remove
                        if (keysToRemove == null)
                        {
                            keysToRemove = new List <object>();
                        }
                        keysToRemove.Add(key);
                    }
                }
                if (keysToRemove != null)
                {
                    foreach (object key in keysToRemove)
                    {
                        _assemblies.Remove(key);
                    }
                }
                if (foundLiveDynamicAssemblies)
                {
                    GCNotificationToken.RegisterCallback(_cleanupCollectedAssemblies, null);
                }
                else
                {
                    _isGCCallbackPending = false;
                }
            }
        }
        private static void CleanupCollectedAssemblies(object state)
        {
            bool          flag = false;
            List <object> list = null;

            lock (syncObject) {
                foreach (object key in _assemblies.Keys)
                {
                    WeakReference weakReference = key as WeakReference;
                    if (weakReference != null)
                    {
                        if (weakReference.IsAlive)
                        {
                            flag = true;
                        }
                        else
                        {
                            if (list == null)
                            {
                                list = new List <object>();
                            }
                            list.Add(key);
                        }
                    }
                }
                if (list != null)
                {
                    foreach (object item in list)
                    {
                        _assemblies.Remove(item);
                    }
                }
                if (flag)
                {
                    GCNotificationToken.RegisterCallback(_cleanupCollectedAssemblies, null);
                }
                else
                {
                    _isGCCallbackPending = false;
                }
            }
        }
        private static AssemblyName GetAssemblyName(Assembly assembly)
        {
            object key = assembly.IsDynamic ? ((ISerializable) new WeakRefKey(assembly)) : ((ISerializable)assembly);

            lock (syncObject) {
                AssemblyName value;
                if (_assemblies == null)
                {
                    _assemblies = new Dictionary <object, AssemblyName>();
                }
                else if (_assemblies.TryGetValue(key, out value))
                {
                    return(value);
                }
                value = new AssemblyName(assembly.FullName);
                _assemblies.Add(key, value);
                if (assembly.IsDynamic && !_isGCCallbackPending)
                {
                    GCNotificationToken.RegisterCallback(_cleanupCollectedAssemblies, null);
                    _isGCCallbackPending = true;
                }
                return(value);
            }
        }