Русский
Русский
English
Статистика
Реклама

Из песочницы Как использовать сторонние сборки в Plug-In

Проблема


Я, и думаю многие разработчики MS Dynamic CRM (в моём случае это 2016 on premise) столкнулись с проблемой, для того что бы использовать сторонние сборки, необходимо их объединять с основной сборкой и потом её регистрировать в Plugin Registration Util.

Как пример многие используют ILMerge или ILRepack.

Поиск


Искал варианты решения на различных площадках, но везде кроме как использования ILMerge или ILRepack, вариантов других не находил. Реализовать задачу хотелось бы так, что бы сборки могли переехать вместе с базой на другой сервер, и всё бы работало без проблем.

Без открытий


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

План


  1. Создание хранилища для сборок
  2. Реализация загрузки сборок в память, по мере необходимости

Реализация



Создание хранилища для сборок


Создаём в базе данных таблицу со следующими полями.



Пример загруженных сборок:



Реализация загрузки сборок в память, по мере необходимости


Я создал библиотеку и назвал её AssemblyLoaderModule.



Конструктор:



Наследуем наш класс от IHttpModule и переопределяем метод Init:



Пишем event метод, который мы добавляем в list event-ов:



Реализуем основной метод который будет вытягивать сбоку из базы



Весь код
using System;
using System.Data.SqlClient;
using System.Reflection;
using System.Web;

namespace CrmExternalAssemblyLoader
{
public class AssemblyLoaderModule: IHttpModule
{
private static bool IsLoaded;
private readonly object _lock = new object();
public void Dispose()
{
throw new NotImplementedException();
}

public void Init(HttpApplication context)
{
lock (_lock)
{
if (!IsLoaded)
{
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
IsLoaded = true;
}
}
}

private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
var assemblyName = new AssemblyName(args.Name);
var assembly = GetAssembly(assemblyName.Name + ".dll");
if (assembly != null)
{
return Assembly.Load(assembly);
}
return null;
}

public byte[] GetAssembly(string assemblyName)
{
var sqlConnString = @Data Source=[database]; Initial Catalog=[catalog]; Integrated Security=true;;
var query = @select Lib
from CrmExternalAssambly
where Name = name;
using (var connection = new SqlConnection(sqlConnString))
{
using (var command = new SqlCommand(query, connection))
{
command.Parameters.Add(new SqlParameter("@name", assemblyName));
connection.Open();
var reader = command.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
return (byte[])reader[0];
}
}
return null;
}
}
}
}
}

Компилим, и подкидываем сборку в папку bin C:\Program Files\Microsoft Dynamics CRM\CRMWeb\bin.

В конфиг добавляем модуль:



Перезагружаем сайт.

Готово.

Когда запустится выполнение плагина, CRM попытается найти сборку в памяти, не найдёт её и полезет в AppDomain.CurrentDomain.AssemblyResolve, там сборка вычитается из базы и загрузится в память домена. Сборка будет жить до тех пор пока не будет перезагружен сайт.

Плюсы\Минусы


+ Вам не нужно мержить сборки в плагин, тем самым размер сборки не будет увеличиваться, не будет большой нагрузки на SQL при запуске плагина, особенно если плагин зарегистрирована в none.
+ Скорость доступа к сборке выше так как она уже загружена в домен.
+ Все сторонние сборки лежат у вас в базе и мигрируют вместе с базой.
+ Возможность хранения сборок разной версии (Этот момент плохо протестирован! Так что есть ещё что проверить)

Возможно при обновлении CRM, нужно будет снова добавить строчку модуля в web.config CRM.
Источник: habr.com
К списку статей
Опубликовано: 22.06.2020 18:15:30
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Crm-системы

Crm

External assembly

Plug-in

Crm 2016

Ms dynamic crm

Категории

Последние комментарии

© 2006-2020, personeltest.ru