Closed Palatis closed 1 year ago
I am working toward similar goals, .net 6, WPF, with this plugin library. I'm just building a simple test solution to exercise the concepts. Mine is working, but it's slightly more simple than yours. I'd be willing to add to mine in the hope of reproducing your problem, but I'm not sure what yours does, especially Plugin1.dll.
I have a Contracts library with just an interface file, defining a method to return a UserControl. Two wpf libraries, each with a custom user control, and separate resource dictionary to define a style it uses. The interface implementation returns an instance of this control. And my wpf test app that finds the two plugins, instantiates, and gets the controls to populate the UI.
So I would need to add the abstract class like you say you have in Plugin1, and any xaml defined in it. Can you share you project or explain it further?
I am having the same problem without WPF (so you can rule that out) as the problem. I have multiple plugins that depend on a common class. The common class is in the plugins directory. I can load the common class, but trying to cast it fails. @natemcmaster - any ideas? Is this something that changed for .NET Core 6, maybe? Edit - another data point - the shared dependency is strongly named (aka signed).
I can load the common class, but trying to cast it fails.
What the failure you're seeing? I'd don't want to commit to this library or others if I'm going to encounter issues like this later.
It's an invalid cast issue. When Plugin1 and Plugin2 are created, they have some common dependency (PluginBase). When loaded, Plugin1 loads PluginBase. When Plugin2 is loaded, it also loads PluginBase. They are considered 2 different types.
In my case, PluginBase is also part of the program LOADING the plugins (call it Main). Main has a PluginBase type, but I can't cast between any of the three.
The documentation says that this should work, so my guess is that something has changed in .NET to break this.
This is in my "Main". I have a separate library for the base class and each of two plugins.
foreach (string dir in Directory.GetDirectories(pluginsDir))
{
var dirName = Path.GetFileName(dir);
var pluginDll = Path.Combine(dir, dirName + ".dll");
if (File.Exists(pluginDll))
{
var loader = PluginLoader.CreateFromAssemblyFile(
pluginDll,
sharedTypes: new[] { typeof(PluginControlBase) });
pluginLoaders.Add(loader);
}
}
foreach (var loader in pluginLoaders)
{
foreach (var pluginType in loader
.LoadDefaultAssembly()
.GetTypes()
.Where(t => typeof(PluginControlBase).IsAssignableFrom(t) && !t.IsAbstract))
{
PluginControlBase pluginControl = (PluginControlBase)Activator.CreateInstance(pluginType);
myPluginControlBases.Add(pluginControl);
}
}
I tried to simulate what I understand you're trying to do. It works for me. But I'm not sure I'm casting in the ways you are. I signed my base plugin library and it still works, though I'm also not sure that simulates what you're doing thoroughly enough. I'd be willing to try to replicate your situation more closely. Or, could you share your solution?
I altered my code this morning to remove the issue (I merged a bunch of plugins to eliminate the issue). Now I can't reproduce the issue - I made a test case and it works. There was some subtle interaction in my old code that caused an issue, but since I can't reproduce this now, I can't help any more. Sorry.
This issue has been automatically marked as stale because it has no recent activity. It will be closed if no further activity occurs. Please comment if you believe this should remain open, otherwise it will be closed in 14 days. Thank you for your contributions to this project.
Closing due to inactivity. If you are looking at this issue in the future and think it should be reopened, please make a commented here and mention natemcmaster so he sees the notification.
I have a WPF+Net6 solution, say:
public interface IPlugin
)public abstract class Plugin1 : IPlugin
)public class Plugin2 : Plugin1
)public class Plugin3 : Plugin1
)Plugin2.dll
andPlugin3.dll
Problem:
When Plugin2 (which refs Plugin1), the xaml (like Plugin1UserControl) loads fine, but Plugin3 fails to find the xaml resources. throws
XamlParseException
complaining about "/Plugin1;component/plugin1usercontrol.xaml" not found.The behavior is pretty random, somethings
Plugin2
gets the xaml, sometimesPlugin1
.I tried:
load all abstract plugins (ie.
Plugin1
with its satellites (ie. NuGet dlls) in this case) into theAssemblyLoadContext.Default
, it complains about InvalidCastException ([A]Plugin2 vs. [B]Plugin2), I also add types from Plugin1 into shared types.but neither of the 4 combinations works.
What can I do now? Currently I'm falling-back to NOT sharing UI classes between plugins (ie. no
Plugin1UserControl
classes). Is there any other solution to this?