AXForum  
Вернуться   AXForum > Блоги > CRM, SharePoint и Черная Магия
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

Добро пожаловать в мой блог! Изначально он не задумывался как блог CRM разработчика, но жизнь сама внесла нужные коррективы. Тут я публикою все свои наблюдения относительно обозначенных в заголовке систем. Если Вы найдете в нем что-то интересное для Вас, как для заказчика, то буду рад сотрудничать с Вами! В моей компетенции 100% задач по MS CRM 3.0/4.0/2011:
  • Консалтинг
  • Проектирование
  • Разработка
  • Обучение


MVP 2010, 2011
Оценить эту запись

Регистрация сборок плагинов с зависимостями

Запись от Артем Enot Грунин размещена 18.09.2017 в 17:35
Обновил(-а) Артем Enot Грунин 20.09.2017 в 16:35
Теги assembly, plugin

Прежде всего, прошу сильно не бить ногами за столь избитую тему, как проблема CRM и зависимых сборок. Проблема стара как мир, казалось бы, ее решение уже найдено, а Microsoft старательно игнорирует проблему уже много лет, но... Недавно я узнал кое что новое по этому вопросу, что, вероятно будет вам интересно.

Итак, всем нам известно, что система не позволяет регистрировать сборки вместе с их зависимостями. Например, вы решили использовать в своем плагине тот же Json.NET, или другую популярную сборку. Система позволит зарегистрировать ваш плагин, но при выполнении вы получите ошибку вида "не удалось загрузить сборку Json.NET, или одну из ее зависимостей". Каноническое решение от Gonzalo Ruiz, думаю тоже всем известно: http://gonzaloruizcrm.blogspot.ru/20...mblies-in.html. Его суть в том, чтобы использовать утиллиту ILMerge от той же Microsoft, чтобы слепить уже существующие сборки в одну. Что удобно, можно даже встроить эту процедуру в процесс сборки решения, что и демонстрирует Gonzalo.

Увы, за все приходится платить. Процесс сборки большого решения с большим числом зависимостей может занимать долгое время (до 20 минут на нашем проекте) и создает некоторые трудности с отладкой. Кроме того, мне не совсем ясна позиция Microsoft относительно этого решения: https://blogs.msdn.microsoft.com/crm...from-plug-ins/. Как отмечает автор:

It isn't blocked, but it isn't supported, as an option for referencing custom assemblies.

Иными словами, прикрыть лавочку уже нельзя, так как лазейкой активно пользуются, но альтенативные решения не были предложены. Однако ясно, что решение не вызывает угрозы безопасности системы, иначе оно не работало бы в онлайн версии.

Так есть ли решение лучше? И да и нет. В поисках альтернативного решения я наткнулся на следующую, довольно популярную статью Jeffrey Richter: https://blogs.msdn.microsoft.com/mic...third-edition/ и несколько реализаций предоженной им концепции. Суть предложенного решения в том, чтобы включить все зависимые сборки в целевую сборку как ресурсы - по сути так же как это делается с вложениями, манифестами, файлами локализации и т.д. и вставить в свой код небольшой сниппет, который зарегиструрует их при помощи обработчика события AppDomain.CurrentDomain.AssemblyResolve. Подход настолько прост и элегантен, что создатель ILMerge Mike Barnett даже написал (в комментарих под этим постом) что не стал бы писать ILMerge, если бы раньше знал об этом способе. В качестве бонуса, это решение позволяет использовать зависимые сборки, которые используют рефлексию или внедрение зависимости, которые могут некорректно работать при использовании ILMerge.

Как оказалось, даже есть примеры его применения в CRM: http://blog.micic.ch/net/dynamics-cr...nced-libraries, хотя автор и не сослался на первоисточник.

Решение не обязательно использовать в лоб, лично я рекомендую использовать вот эту реализацию предложенного подхода: https://github.com/Fody/Costura. После установки, этот пакет автоматически встроится в борку проекта и на выходе вы получите то что хотели. При этом, вам даже не потребуется изменять Build Action и выполнять любые другие манипуляции!

Однако, сильнее радости было лишь разочарование. Этот подход не будет работать в "посочнице" и, соответственно, в онлайн версии. Увы, в песочнице CRM, среди всего прочего, нельзя прикасаться к событию AppDomain.CurrentDomain.AssemblyResolve: http://jerhome.blogspot.ru/2014/04/m...dbox-mode.html, что сводит на нет все усилия.

Тем не менее, решение отлично работает без изоляции на он премис. В моем случае, этого вполне достаточно. Будем надеяться, рано или поздно, Microsoft обратит внимание на проблему, и нам больше не придется выбирать, меньшее из двух зол.

Добавлено 20.09.2017:
Перспектива избавиться от ILMerge оказалась столь заманчива, что мне пришлось потратить еще день, чтобы окончательно развеять иллюзии. Мной двигал посыл, что если нельзя использовать событие AppDomain.CurrentDomain.AssemblyResolve, то, вероятно, должен быть другой способ "напихать" в контекст нужные сборки. В своих поисках я набрел на статью, которая объясняет как работает вся концепция загрузки сборок: https://docs.microsoft.com/en-us/dot...sembly-loading. Цитирую:

Assemblies that are loaded from byte arrays are loaded without context unless the identity of the assembly, which is established when policy is applied, matches the identity of an assembly in the global assembly cache; in that case, the assembly is loaded from the global assembly cache

А теперь фаталити:

Loading assemblies without context has the following disadvantages: Other assemblies cannot bind to assemblies that are loaded without context, unless you handle the AppDomain.AssemblyResolve event.

Именно это я и наблюдал на практике: мне удалось успешно загрузить зависимую сборку в домен, но она все равно не биндилась из основной.

Увы, у меня кончились идеи, как еще можно реализовать загрузку зависимостей не изменяя сам подход к разработке. Из "маразмов" есть мысль попробовать разместить в основной сборке только "инжектор", а сам плагин и его зависимости грузить и исполнять в отдельном домене. Иными словами, повторить то что делает Microsoft и засунуть их матрешку в свою. Скорее всего, при таком подходе я не смогу напрямую работать с OrganizationContext и вызовы между доменами придется проксировать, но это уже совсем другой пост...
Размещено в CRM
Просмотров 45891 Комментарии 0
Всего комментариев 0

Комментарии

 


Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 22:39.