Answer the question
In order to leave comments, you need to log in
How to solve the problem of dynamically connecting assemblies of an extensible application?
Good afternoon. Faced the following problem:
I wanted to make an application that checks the folder for plug-in assemblies and loads them dynamically. When pluggable assemblies do not contain references to other assemblies, everything works fine. But when assemblies refer to methods of other local assemblies, an exception is thrown that the assembly was not found, which is logical, since the assembly is not loaded into the domain. It’s just that commercial applications (for example, Revit) calmly process such references, it’s enough to implement the necessary interfaces in the main assembly, and if my assembly contains references to other assemblies during the execution of the interface method, then they don’t have any exceptions and the methods are called. The question is how can this problem be solved and how do commercial applications solve this problem?
In more detail, an explanatory example:
The code of the main application in the Modules folder which contains the StarterLib.dll and HelloWorld.dll assemblies:
class Program
{
static void Main(string[] args)
{
LoadAssembliesModules();
Console.ReadLine();
}
private static void LoadAssembliesModules()
{
string modulespath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "//Modules";
var AddInAssemblies = Directory.EnumerateFiles(modulespath, "*.dll");
var AddInTypes = from file in AddInAssemblies
let assembly = Assembly.LoadFile(file)
from t in assembly.ExportedTypes // Открыто экспортируемые типы
// Тип может использоваться, если это класс, реализующий IStart
where t.IsClass &&
typeof(IStart).GetTypeInfo().IsAssignableFrom(t.GetTypeInfo())
select t;
foreach (Type t in AddInTypes)
{
IStart ai = (IStart)Activator.CreateInstance(t);
if (ai != null)
{
ai.Start();
}
}
}
}
public class Class1: IStart
{
public void Start()
{
Console.WriteLine("Hello");
//Не работает если убрать комментарии ниже:
//Hello h = new Hello();
//h.StartHello();
}
}
public class Hello
{
public void StartHello()
{
System.Windows.Forms.MessageBox.Show("Hello World");
}
}
Answer the question
In order to leave comments, you need to log in
Everything is simple. Implement your own code
AppDomain.AssemblyResolve += OnAssemblyResolve;
And in OnAssemblyResolve load the requested assemblies into the domain
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question