Динамическая загрузка dll библиотек C# winforms
У меня есть следующий код для загрузки dll из папки:
private List<IBookFormatPlugin> LoadPlugins(string pluginsDirectory)
{
List<IBookFormatPlugin> plugins = new List<IBookFormatPlugin>();
// Получение всех файлов .dll из папки pluginsDirectory
string[] dllFiles = Directory.GetFiles(pluginsDirectory, "*.dll");
foreach (string dllFile in dllFiles)
{
try
{
// Загрузка сборки
Assembly pluginAssembly = Assembly.LoadFrom(dllFile);
string pluginName = pluginAssembly.GetName().Name;
Console.WriteLine($"Имя сборки DLL: {pluginName}");
// Получение версии сборки
Version version = pluginAssembly.GetName().Version;
Console.WriteLine($"Версия: {version}");
object[] titleAttributes = pluginAssembly.GetCustomAttributes(typeof(AssemblyTitleAttribute), false);
if (titleAttributes.Length > 0)
{
AssemblyTitleAttribute titleAttribute = (AssemblyTitleAttribute)titleAttributes[0];
Console.WriteLine($"Название: {titleAttribute.Title}");
}
object[] descriptionAttributes = pluginAssembly.GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false);
if (descriptionAttributes.Length > 0)
{
AssemblyDescriptionAttribute descriptionAttribute = (AssemblyDescriptionAttribute)descriptionAttributes[0];
Console.WriteLine($"Описание: {descriptionAttribute.Description}");
}
// Получение всех типов, реализующих интерфейс IBookFormatPlugin
Type[] pluginTypes = pluginAssembly.GetTypes().Where(t => typeof(IBookFormatPlugin).IsAssignableFrom(t) && !t.IsInterface).ToArray();
Console.WriteLine(pluginTypes.Length);
// Создание экземпляров плагинов и добавление их в список
foreach (Type pluginType in pluginTypes)
{
IBookFormatPlugin plugin = (IBookFormatPlugin)Activator.CreateInstance(pluginType);
plugins.Add(plugin);
}
}
catch (Exception ex)
{
// Обработка ошибок загрузки плагина
Console.WriteLine($"Ошибка загрузки плагина из файла {dllFile}: {ex.Message}");
}
}
return plugins;
}
А также несколько библиотек dll
образованных от интерфейса IBookFormatPlugin
Пример одной из них:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using VersOne.Epub;
namespace epubPlugin
{
public class epubReader : IBookFormatPlugin
{
bool IBookFormatPlugin.CanReadFormat(string filePath)
{
...
}
string IBookFormatPlugin.FilterFormat()
{
...
}
Book IBookFormatPlugin.InfoBook(string filePath)
{
...
}
string IBookFormatPlugin.ReadBook(string filePath)
{
...
}
}
}
Вот также сам интерфейс:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace epubPlugin
{
public interface IBookFormatPlugin
{
bool CanReadFormat(string filePath);
Book InfoBook(string filePath);
string ReadBook(string filePath);
string FilterFormat();
}
}
Проблема в том что LoadPlugins
возвращает пустой список.
Подскажите пожалуйста, в чем ошибка?
Ответы (1 шт):
Автор решения: RupKO
→ Ссылка
Ошибка была в том что я не учитывал пространство имен для интерфейса
object[] descriptionAttributes = pluginAssembly.GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false);
if (descriptionAttributes.Length > 0)
{
AssemblyDescriptionAttribute descriptionAttribute = (AssemblyDescriptionAttribute)descriptionAttributes[0];
Console.WriteLine($"Описание: {descriptionAttribute.Description}");
}
string iMyInterfaceName = "." + typeof(IBookFormatPlugin).ToString();
Type[] defaultConstructorParametersTypes = new Type[0];
object[] defaultConstructorParameters = new object[0];
foreach (Type type in pluginAssembly.GetTypes())
{
string ns = type.Namespace;
if (type.GetInterface(ns + iMyInterfaceName) != null)
{
ConstructorInfo defaultConstructor = type.GetConstructor(defaultConstructorParametersTypes);
object instance = defaultConstructor.Invoke(defaultConstructorParameters);
plugins.Add(instance as IBookFormatPlugin);
}
}