I’ve been trying to use this C# .NET Core tutorial: creating-app-with-plugin-support for let’s call it “plugin pattern” to create an application which would allow to use an arbitrary deep structure of master/plugin classes e.g. instead of having one main app which loads different assemblies as plugins and correctly resolves their dependencies I wanted to have those plugins become “masters” for their plugins too.
So from user perspective, given URL has form:
Scenario 1:
Master (uses IMasterPlugin interface from dedicated assembly for interfaces "interop")
+-- Plugin1 (implementing interface IMasterPlugin)
+-- Plugin2 (implementing interface IMasterPlugin)
I want to have:
Scenario 2:
Master
+-- Plugin1 (uses IPlugin1Plugin interface from other dedicated assembly for interface "interop")
+-- SubPlugin1 (implementing different interface IPlugin1Plugin)
+-- SubPlugin2 (implementing different interface IPlugin1Plugin, uses IPlugin2SubPlugin)
+-- SubSubPlugin1 (implements IPlugin2SubPlugin)
+-- SubSubPlugin2 (implements IPlugin2SubPlugin)
+-- SubSubPlugin3 (implements IPlugin2SubPlugin)
...
+-- Plugin2
Interface names are arbitrary it is the structure I wanted to present. Structure where every plugin is a different assembly residing in different directory having issues with depending on same assemblies of different version (that’s why I need isolation). Of course all plugins resides “under” the main ‘Master’ directory so the structure of scenario 1 and 2 is also structure of directories.
Problem
Using aforementioned link works flawlessly in case of scenario 1. In case of scenario 2, whenever I try to load an assembly I’m stuck with unresolved assemblies – something that pattern should handle. Yes I’ve used same .NET (8) for everything. SubPlugins have dependencies on various nugets with their own dependencies (hence I need isolation)
Question(s)
How to implement scenario 2 using tools (approach) from tutorial? I don’t require code, more like a hint why the tutorial code might fail in case of scenario 2. Also the statement that “Yes it should work for scenario 2, you’re doing something wrong” or “No, scenario 2 needs a different approach” will help.
I tried to use structure from page:
MasterApp <------- MasterAppPluginInterop (contains interface IPlugin)
| |
+--- Plugin <-----------+
where MasterApp contains plugin loader (static class) and bend it to my needs:
MasterApp <------- MasterAppPluginInterop
|
| +--------+ |
+---+ Plugin | <-----------+
+--------+ <--------------- SubPluginInterop (contains interface ISubPlugin)
| |
+---- SubPlugin <-------------+
where Plugin contains different static class (different name) doing the same as the one from page but for ISubPlugin interface.
The part of the plugin loader code, which loads the assembly:
protected override Assembly Load(AssemblyName assemblyName)
{
string assemblyPath = _resolver.ResolveAssemblyToPath(assemblyName);
if (assemblyPath != null)
{
return LoadFromAssemblyPath(assemblyPath);
}
return null;
}
this part loads the assembly, but the returned Assembly does not have types (property ‘DefinedTypes’ throws an exception also call to GetType()). And the problem / exception is that it cannot find “SubPluginInterop” assembly (which is clearly on the place where it should be).
I have recreated all the settings for project files as it was demanded by the web page.