Как можно загрузить встроенные ресурсы DLL в виде библиотеки с использованием Assembly?

У меня есть приложение, для которого я разработал поддержку плагинов и создал собственную библиотеку для их реализации. Я использую <code class="cs">Assembly</code> и <code class="cs">AssemblyLoadContext</code> для загрузки, и всё функционирует нормально. Однако, при добавлении сторонней библиотеки, такой как NAudio, в плагин и попытке загрузить его в приложение, возникла ошибка: <blockquote>Could not load file or assembly 'NAudio'</blockquote> . 

Я решил встроить NAudio в плагин как ресурс, и теперь он находится в основной библиотеке. Я могу получить его путь с помощью <code class="cs">Assembly.GetManifestResourceNames()</code>. Но у меня возникли трудности с тем, как динамически загрузить NAudio в моём приложении, чтобы плагин работал корректно. Можете помочь с этой задачей? Спасибо!
  • 8 апреля 2025 г. 19:35
Ответы на вопрос 2
Да, можно встроить DLL как ресурс в сборку и загрузить ее динамически в ваше приложение. Вот шаги, которые вам нужно выполнить для этого:

1. **Добавьте NAudio в ваш плагин как ресурс**:

   Убедитесь, что вы добавили файл NAudio.dll как встроенный ресурс в ваш проект плагина. Это можно сделать, щелкнув правой кнопкой мыши на файле NAudio.dll в обозревателе решений, выбрав свойства и установив "Build Action" на "Embedded Resource".

2. **Загрузите встроенный ресурс в выполнение**:

   Вам необходимо извлечь NAudio.dll из ресурсов и загрузить его в ваше приложение. Вы можете сделать это с помощью `AssemblyLoadContext`.

Вот пример кода, который показывает, как это сделать:

```csharp
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;

public class PluginLoader : AssemblyLoadContext
{
    public PluginLoader() : base(isCollectible: true) { }

    protected override Assembly Load(AssemblyName assemblyName)
    {
        // Здесь мы ищем и загружаем только нужные сборки, если они есть в ресурсах
        if (assemblyName.Name == "NAudio")
        {
            // Загружаем ресурс
            using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("YourNamespace.NAudio.dll")) // Замените YourNamespace на фактическое пространство имен
            {
                if (stream == null)
                {
                    throw new Exception("Resource not found.");
                }

                byte[] assemblyData = new byte[stream.Length];
                stream.Read(assemblyData, 0, assemblyData.Length);

                return Assembly.Load(assemblyData);
            }
        }

        return null; // Возвращаем null для сборок, которые не нужно загружать
    }
}

// Пример использования
class Program
{
    static void Main(string[] args)
    {
        var loader = new PluginLoader();
        Assembly pluginAssembly = loader.LoadFromAssemblyPath("PathToYourPlugin.dll"); // Путь к вашему плагину

        // Здесь можно вызвать методы из плагина
    }
}
```

3. **Наблюдайте за пространством имен и именем ресурса**:

   Убедитесь, что вы указали правильное пространство имен и имя ресурса при извлечении встроенного ресурса с помощью `GetManifestResourceStream`. Имя ресурса обычно имеет вид: `Namespace.FolderName.FileName`, если файл находится в папке.

4. **Используйте загруженную библиотеку**:

   После того как вы загружаете `NAudio` с помощью вашего `PluginLoader`, вы должны иметь возможность использовать его функционал через ваш плагин, как если бы библиотека была обычным файлом DLL.

5. **Обработка зависимостей**:

   Если NAudio имеет дополнительные зависимости, вы также должны убедиться, что они доступны. Вам нужно будет добавить их как встроенные ресурсы и загрузить аналогичным образом, если они не могут быть найдены самими плагинами.

С помощью этих шагов вы сможете динамически загружать встроенные DLL и успешно использовать их в вашем приложении с поддержкой плагинов.
А mef и maf уже отменили или есть какие-то идеолого-религиозные неприятия оных?
Похожие вопросы