Example #1
0
        int UnLoadAsmRef(SeparatedAssembly asm, Dictionary <SeparatedAssembly, bool> collection)
        {
            if (!collection[asm])
            {
                m_assemblyDisposeCounter++;
                collection[asm] = true;
            }

            //получаем разницу между загруженными сборками и "выгруженными"
            return(collection.Count - m_assemblyDisposeCounter);
        }
Example #2
0
        /// <summary>
        /// Загрузка сборки в AppDomain
        /// </summary>
        /// <param name="fInfo">Информация о файле сборки</param>
        /// <param name="name">Имя сборки</param>
        /// <param name="hash">HASH файла</param>
        /// <returns>Возвращает обёртку над выгруженной сборкой</returns>
        internal SeparatedAssembly LoadAssembly(FileInfo fInfo, AssemblyName name, string hash)
        {
            lock (m_locker)
            {
                if (m_disposed)
                {
                    throw new ObjectDisposedException($"Домен был выгружен перед загрузкой сборки '{(fInfo?.Name ?? "NULL")}'");
                }

                //получаем экземпляр из другого AppDomain
                var extAsm = (ExternalAppDomainAssembly)m_domain.CreateInstanceAndUnwrap(CoreAssemblyName, ExternalAppDomainAssembly.TypeFullName);
                extAsm.BindAssembly(fInfo.FullName);

                var asm = new SeparatedAssembly(extAsm, this);
                asm.AssemblyName = name;
                asm.FileHash     = hash;
                asm.UnLoaded    += OnAssemblyDispose;
                m_loadedAssemblies.Add(asm, false);

                return(asm);
            }
        }
Example #3
0
        void OnAssemblyDispose(SeparatedAssembly asm)
        {
            if (asm == null)
            {
                return;
            }

            /*
             * попадаем сюда при явном вызове клиентом Dispose у сборки
             *
             * поскольку её фактически из домена выгрузить нельзя
             * то ведём учёт "выгруженных"
             */
            var asmCount = -1;

            lock (m_locker)
            {
                if (m_loadedAssemblies.ContainsKey(asm))
                {
                    asmCount = UnLoadAsmRef(asm, m_loadedAssemblies);
                }
                else if (m_relatedAssemblies.ContainsKey(asm))
                {
                    asmCount = UnLoadAsmRef(asm, m_relatedAssemblies);
                }
            }

            //выгружаем текущий домен, если все его сборки помечены как "выгружена"
            if (asmCount == 0)
            {
                if (!m_Managed) //если домен был создан не явно
                {
                    Dispose();  //самоликвидируемся
                }
            }
        }