На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Страницы: (2) [1] 2  все  ( Перейти к последнему сообщению )  
> Run-time загрузка, пересборка библиотек
    Столкнулся с проблемой.
    Библиотеки написаны на c#. Первую библиотеку, библиотеку1, подключаю из c++ проекта (run-time - это когда запущен этот проект). Охота из dll в run-time (т.е. когда ее используют) подключить другую библиотеку, библиотеку2, (тоже c#) и поюзать ее методы.
    При этом ставится еще одно условие! Что бы не останавливая run-time проекта пересобирать библиотеку2.
    Как это сделать?
      Цитата

      Охота из dll в run-time (т.е. когда ее используют) подключить другую библиотеку, библиотеку2, (тоже c#) и поюзать ее методы.

      В .NET лучше ссылку добавить в reference сборки, чтобы подгрузилась при загрузке. Зачем тебе в рантайм? Память экономишь? Забудь, та же ХР скажем все равно это закеширует в каком-нить Prefetch и ничего ты не выиграешь. LoadLibrary это вчерашний день.
      Цитата

      При этом ставится еще одно условие! Что бы не останавливая run-time проекта пересобирать библиотеку2.
      Как это сделать?

      Тут я тебя не понял
        Как раз хочу обойтись без reference.
        К примеру, я передаю методу из dll имя библиотеки, которую надо загрузить и выполнить метод, имя которого я знаю. При этом имя может быть произвольное, да и в следующем вызове, та же самая библиотека может быть пересобрана (между вызовами).
        А LoadLibrary - в c# нету. Или я ошибаюсь?
          Цитата DarkKo, 15.09.03, 11:06:44
          Как раз хочу обойтись без reference.
          К примеру, я передаю методу из dll имя библиотеки, которую надо загрузить и выполнить метод, имя которого я знаю.

          Такие вещи делаются через рефлекшн. смотри Activator. Загружаешь нужный тебе тип и вызываешь нужный метод (Invoke)
          Цитата

          При этом имя может быть произвольное, да и в следующем вызове, та же самая библиотека может быть пересобрана (между вызовами).
          А LoadLibrary - в c# нету. Или я ошибаюсь?

          Assembly.LoadFrom или Assembly.LoadWithPartialName
          Сообщение отредактировано: kl -
            Загрузить библиотеку получилось!
            Спасибо!
            ExpandedWrap disabled
              <br>Assembly SecondScriptAssembly;<br>SecondScriptAssembly = Assembly.LoadFrom("...\\dinamo.dll");<br>Object fromdll = SecondScriptAssembly.CreateInstance("dinamo.PrintMessage");<br>MethodInfo Method;<br>Method = SecondScriptAssembly.GetTypes()[0].GetMethod("Message");<br>Object [] paramasa = new object[1];<br>paramasa[0] = "Importede string\n";<br>Method.Invoke(fromdll,paramasa);<br>


            А вот как теперь ее выгрузить, что бы пересобрать, например? Т.е. что бы эта dinamo.dll освободилась!
              Цитата DarkKo, 15.09.03, 12:58:56
              Загрузить библиотеку получилось!
              Спасибо!
              ExpandedWrap disabled
                <br>... skipped...<br>

              А вот как теперь ее выгрузить, что бы пересобрать, например? Т.е. что бы эта dinamo.dll освободилась!

              Ответ краткий - никак. Серьезно.
              Подробнее - грузить ее в отдельный AppDomain и делать ему Unload. Тогда выгрузятся все сборки в него загруженные
                Так, тогда придется делать некий менеджер, который будет постоянно прибавлять порядковый номер файла (библиотеки) при сборке и в следующий раз загружить именно его! Криво. Но что делать? Раз так задача стоит. :)
                  Цитата DarkKo, 15.09.03, 13:14:08
                  Так, тогда придется делать некий менеджер, который будет постоянно прибавлять порядковый номер файла (библиотеки) при сборке и в следующий раз загружить именно его! Криво. Но что делать? Раз так задача стоит. :)

                  Зачем??? Сборка уже в метаданных содержит номер версии. А домен придется перегружать при изменении версии, вот и весь менеджер
                  Assembly.GetName().Version
                  Сообщение отредактировано: kl -
                    Хорошая мысль с доменом! Это гениально.

                    А почему у меня вот так сразу не загружается библиотека в домен?
                    (на третьей строчке ошибка)
                    ExpandedWrap disabled
                      <br>AppDomain Domen = AppDomain.CreateDomain("Domen Addition Dll");<br>Assembly SecondScriptAssembly;<br>SecondScriptAssembly = Domen.Load(filename);<br>
                      Цитата DarkKo, 15.09.03, 14:29:53

                      AppDomain Domen = AppDomain.CreateDomain("Domen Addition Dll");
                      Assembly SecondScriptAssembly;
                      SecondScriptAssembly = Domen.Load(filename);

                      Попробуй так.
                      ExpandedWrap disabled
                        <br>// Set up the Evidence<br>Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;<br>Evidence evidence = new Evidence(baseEvidence);<br>evidence.AddAssembly("(some assembly)");<br><br>// Create the AppDomain      <br>AppDomain newDomain = AppDomain.CreateDomain("newDomain", evidence);<br>

                      Просто проблема при загрузке сборки в домен, не являющийся текущим для приложения. Смотри AppDomain.Load раздел Remarks
                      Сообщение отредактировано: kl -
                        Зачем в evidence добавлять сборку - не понимаю.
                        Пытаюсь сделать вот так:
                        ExpandedWrap disabled
                          <br>AppDomain Domen = AppDomain.CreateDomain("NewDomain");<br>try<br>{<br>Object fromdll = Domen.CreateInstanceFromAndUnwrap(filename, "dinamo.PrintMessage");<br>}<br>

                        И при этом ловлю exception:
                        SerializationException
                        Который мне говорит, что мойе сборки (перечисляет ее имя) найти не может.
                          кстати при создании домена передай еще сетап с ShadowCopyFiles = true - тогда сможешь сборку на новую заменить
                          Я не помню, там были какие-то траблы с этим, но сейчас проверить не могу... надо поэкспериментировать, например загрузить сборку из Гака или передать strong name. Насчет strong name особенно актуально если у тебя фреймворк 1.1
                          Сообщение отредактировано: kl -
                            Знаешь что я подумал! Я полумал, что текущий домен можно сделать с ShadowCopyFiles = true. Посмотрим, получится или нет.
                            Framework у меня действительно 1.1
                            А с GAC я не пробовал. Чем это поможет?
                              Когда на текущий домен ставишь SetShadowCopyFiles(), то пересборка dll возможна. Т.к. библиотека была куда-то скопирована и от туда юзается. Но при следующем вызове LoadFrom уже не получается достать новую библиотеку. Как он себе копию сделал, так ее и использует.
                              А в новый домен так и не получается сборку засосать.
                                Да ты прав, я наверное глупость сказал вчера, совсем забыл, что при загрузке сборки в нетекущий домен - она автоматом загрузится и в текущий. Иначе невозможен обмен данными. Извиняй - давно это уже было
                                Если у тебя 1.1, то скорее всего он от тебя хочет strong name сборки. ГАК я посоветовал чисто для эксперимента, типа найдет/не найдет
                                И последнее: учти что при загрузке сборки в отдельный домен все взаимодействие пойдет через ремоутинг, со всеми вытекающими:
                                1) Передаваемые в качестве параметров и возвращаемого значения типы должны быть сериализуемыми.
                                2) Сборка должна быть загружена и в вызывающем домене и в выполняющем
                                3) Если объект передается по значению, то при попытке доступа к нему тебе отдадут копию.
                                4) Статик-переменные в разных доменах разные
                                5) Если объект передается по ссылке то доступ к нему происходит через прокси, что сказывается на скорости вызова не в лучшую сторону

                                А подгрузить новую он и не даст, т.к. это равнозначно выгрузке старой! Кто будет проверять совместимость типов например? Представь что у тебя у клиента остались ссылки на типы из старой сборки, а тут ты раз и меняешь ее на новую. в .NET такое никогда не позволяется, код должен быть безопасен. Наверное среда могла быть проверять и кидать что-нить типа TypeUnloadException но тогда извини - теряем в производительности. В общем хочешь пересобирать на лету - экспериментируй с отдельным доменом
                                Сообщение отредактировано: kl -
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0405 ]   [ 16 queries used ]   [ Generated: 2.05.24, 12:49 GMT ]