Пример #1
0
        /// <summary>
        /// Создание нового домена
        /// </summary>
        /// <returns>Возвращает новый экземпляр с новым доменом для текущей сессии</returns>
        internal SeparatedAppDomain CreateDomain()
        {
            var domain = new SeparatedAppDomain(this);

            lock (SessionLocker)
                Domains.Add(domain);

            return(domain);
        }
Пример #2
0
        /// <summary>
        /// Добавление домена в сессию
        /// </summary>
        /// <param name="domain">Домен</param>
        internal void Add(SeparatedAppDomain domain)
        {
            if (domain == null)
            {
                return;
            }

            try
            {
                lock (SessionLocker)
                    Domains.Add(domain);

                domain.Disposed += OnDomainDisposed;
            }
            catch (Exception ex)
            {
                m_Loger.Log("Возникло исключение при добавлении домена в сессию", ex
                            , new LogParameter("ID сессии", ID.ToString()));
            }
        }
Пример #3
0
        /// <summary>
        /// Учёт выгрузки Домена в Сессии
        /// </summary>
        /// <param name="domain">Выгружаемый домен</param>
        internal void OnDomainDisposed(SeparatedAppDomain domain)
        {
            if (domain == null)
            {
                return;
            }

            domain.Disposed -= OnDomainDisposed;

            var dCount = 0;

            lock (SessionLocker)
            {
                Domains.Remove(domain);

                dCount = Domains.Count;
            }

            if (dCount == 0)
            {
                Dispose();
            }
        }
Пример #4
0
        /// <summary>
        /// Загрузка библиотеки в сессию
        /// </summary>
        /// <param name="asmFile"></param>
        /// <returns></returns>
        internal SeparatedAssembly LoadAssembly(FileInfo asmFile)
        {
            try
            {
                string pathName = asmFile.FullName;
                //получение информации о сборке без загрузки в домен
                //https://stackoverflow.com/questions/30306702/assemblyinfo-without-loading
                var name = AssemblyName.GetAssemblyName(pathName);

                /*
                 * получение уникального HASH'а файла
                 * на случай, если грузятся разные файлы (даже по названию), но это одна сборка
                 * по хешу смотрим, одинаковые ли файлы или нет
                 *
                 * теоретически, возможны ложные срабатывания проверки
                 * когда одну сборку переименовали в другую и их хэш совпал
                 * но вероятность подобного крайне мала ;)
                 */
                var asmHash = Utilites.GetFileHash(pathName);

                SeparatedAppDomain domain = null;
                bool same = false; //флаг, что нашли домен с такой же сборкой (и таким же файлом)
                lock (SessionLocker)
                {
                    foreach (var dom in Domains)
                    {
                        var loadedState = dom.HasLoaded(name, asmHash);

                        switch (loadedState)
                        {
                        case LoadedState.NotLoaded:
                            //если текущий домен свободен - грузим сюда

                            domain = dom;
                            break;

                        case LoadedState.LoadedDifferent:
                            //если занят - проверяем следующий. Может быть свободен
                            continue;

                        case LoadedState.LoadedSame:
                            //если точно такая же уже загружена - выдаём её же
                            domain = dom;
                            same   = true;
                            break;
                        }

                        //если есть куда
                        if (domain != null)
                        {
                            break;
                        }
                    }
                }

                //если имеющиеся домены не подходят для загрузки
                //в них уже есть сборки со схожим именем, но из других файлов
                if (domain == null)
                {
                    //создаём новый домен в текущей сессии
                    domain = CreateDomain();
                }

                //загрузка новой сборки в домен
                return(same
                    ? domain.GetAssembly(name)                      //выдаём уже загруженный ранее файл
                    : domain.LoadAssembly(asmFile, name, asmHash)); //загружаем новую сборку
            }
            catch (Exception ex)
            {
                return(new SeparatedAssembly(ex));
            }
        }
Пример #5
0
 internal SeparatedAssembly(ExternalAppDomainAssembly asm, SeparatedAppDomain domain)
 {
     m_externalAsmWrapper = asm;
     Domain = domain;
 }