У меня есть приложение .NET 8.0, использующее MEF (System.Composition) в качестве подключаемой архитектуры. Большинство плагинов работают правильно, однако есть пара, которая генерирует исключения во время выполнения. У обоих этих плагинов есть одна общая черта: они полагаются на библиотеки, которые используют собственные библиотеки DLL из папки «время выполнения». У одного есть Microsoft.Web.WebView2, а у другого — LiveCharts2, который использует Skia. У них есть деревья времени выполнения, которые выглядят следующим образом (например, для плагина живых диаграмм):
runtimes
|-- osx
| `-- native
| |-- libHarfBuzzSharp.dylib
| `-- libSkiaSharp.dylib
|-- win-arm64
| `-- native
| |-- libHarfBuzzSharp.dll
| `-- libSkiaSharp.dll
|-- win-x64
| `-- native
| |-- libHarfBuzzSharp.dll
| `-- libSkiaSharp.dll
`-- win-x86
`-- native
|-- libHarfBuzzSharp.dll
`-- libSkiaSharp.dll
Плагин веб-просмотра имеет то же дерево, только с разными DLL. Папка времени выполнения — это каталог сборки проекта рядом с его dll.
Я могу заставить эту систему работать, переместив зависимости в хост-приложение (т. е. webview2 и Skia), но это, очевидно, не идеально, поскольку любой будущий плагин, который хочет использовать собственную библиотеку, должен будет добавить свои зависимости к хосту.
Если у меня нет Skia в хост-приложении, плагин livecharts выдаст ошибку :
DllNotFoundException: Unable to load DLL 'libSkiaSharp' or one of its dependencies: The specified module could not be found. (0x8007007E)
Вот код загрузки моего плагина:
private void Init(IEnumerable assemblies)
{
_pluginManager.ImportsSatisfied += OnImportsSatisfied;
var configuration = new ContainerConfiguration()
.WithAssemblies(assemblies);
try
{
using (CompositionHost host = configuration.CreateContainer())
{
host.SatisfyImports(_pluginManager);
}
}
catch (ReflectionTypeLoadException ex)
{
Log.Error("Could not load extension pluginNames: {0}\nLoader exceptions:{1} ", ex, ex.LoaderExceptions);
}
catch (Exception ex)
{
Log.Error("Could not load extension pluginNames: {0}", ex);
}
}
Где сборки — это список сборок, загруженных с помощью:
private static IEnumerable GetAssembliesFromNames(IEnumerable pluginNames, string pluginDirectory)
{
List assemblies = new();
foreach (string pluginName in pluginNames)
{
try
{
assemblies.Add(GetAssemblyForPluginByName(pluginName, pluginDirectory));
}
catch (Exception ex)
{
Log.Error("Could not load plugin assembly {0}: {1}", pluginName, ex);
}
}
return assemblies;
}
public static Assembly GetAssemblyForPluginByName(string name, string workingDirectory)
{
string pluginName = Path.GetFileName(name);
string pluginFolderFilePath = Path.Combine(workingDirectory, pluginName);
string pluginDllPath = Path.Combine(pluginFolderFilePath, pluginName + ".dll");
if (Directory.Exists(pluginFolderFilePath) && File.Exists(pluginDllPath))
{
return Assembly.LoadFrom(pluginDllPath);
}
throw new FileNotFoundException(name);
}
Подробнее здесь: https://stackoverflow.com/questions/786 ... mef-plugin
Загрузка собственных зависимостей для плагина MEF ⇐ C#
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Библиотека C ++ для поиска собственных значений и собственных векторов матрицы [закрыто]
Anonymous » » в форуме C++ - 0 Ответы
- 14 Просмотры
-
Последнее сообщение Anonymous
-
-
-
MEF и ShadowCopying DLL, чтобы я мог перезаписывать их во время выполнения.
Anonymous » » в форуме C# - 0 Ответы
- 17 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Можно ли избежать исключения TypeLoadException в MEF для необязательных типов?
Anonymous » » в форуме C# - 0 Ответы
- 13 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Можно ли избежать исключения TypeLoadException в MEF для необязательных типов?
Anonymous » » в форуме C# - 0 Ответы
- 21 Просмотры
-
Последнее сообщение Anonymous
-