C
C#10mo ago
Pdawg

Plugin system not casting properly

I'm trying to make a plugin system for my app, which does this:
public void LoadAndRunPlugins()
{
foreach (string dllFile in Directory.GetFiles(pluginDirectory, "*.dll"))
{
try
{
Assembly assembly = pluginLoadContext.LoadFromAssemblyPath(Path.GetFullPath(dllFile));

foreach (Type type in assembly.GetTypes().Where(asm => !asm.FullName.Contains("GyroShell.Library")))
{
if (type.GetInterface("IPlugin") != null)
{
IPlugin plugin = Activator.CreateInstance(type) as IPlugin;
plugin.Initialize();
}
}
}
catch (Exception ex)
{
Debug.WriteLine($"[-] PluginManager: Error loading and running plugin from {dllFile}: {ex.Message}");
}
}
}
public void LoadAndRunPlugins()
{
foreach (string dllFile in Directory.GetFiles(pluginDirectory, "*.dll"))
{
try
{
Assembly assembly = pluginLoadContext.LoadFromAssemblyPath(Path.GetFullPath(dllFile));

foreach (Type type in assembly.GetTypes().Where(asm => !asm.FullName.Contains("GyroShell.Library")))
{
if (type.GetInterface("IPlugin") != null)
{
IPlugin plugin = Activator.CreateInstance(type) as IPlugin;
plugin.Initialize();
}
}
}
catch (Exception ex)
{
Debug.WriteLine($"[-] PluginManager: Error loading and running plugin from {dllFile}: {ex.Message}");
}
}
}
The IPlugin instance is null, so calling plugin.Initialize() throws an NRE. The thing is, it should work just fine, given my plugin code:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GyroShell.Library.Interfaces;

namespace TestGyroShellModule
{
public class PluginRoot : IPlugin
{
//public IPluginInfo PluginInformation => new PluginInfo();

public void Initialize()
{
Debug.WriteLine("We're alive from test plugin!");
}

public void Shutdown()
{
// Shutdown logic
}

/*private class PluginInfo : IPluginInfo
{
public string Name => "Test GyroShell Plugin";
}*/
}
}
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GyroShell.Library.Interfaces;

namespace TestGyroShellModule
{
public class PluginRoot : IPlugin
{
//public IPluginInfo PluginInformation => new PluginInfo();

public void Initialize()
{
Debug.WriteLine("We're alive from test plugin!");
}

public void Shutdown()
{
// Shutdown logic
}

/*private class PluginInfo : IPluginInfo
{
public string Name => "Test GyroShell Plugin";
}*/
}
}
And yes, they both reference the same exact interface, defined in GyroShell.Library.Interfaces. Lastly, I've tried debugging this and nothing should go wrong. It tries to cast the PluginRoot class to an IPlugin, which should work since it properly implements the interface, but it just fails. No exceptions are thrown.
40 Replies
br4kejet
br4kejet10mo ago
I'd do if (typeof(IPlugin).IsAssignableFrom(type))
Pdawg
PdawgOP10mo ago
Okay, I'll try this There's not an NRE anymore, but now it just fails to cast. Once again, no exceptions are thrown, and it should work just fine The test plugin references GyroShell.Library, so it's definitely implementing the correct interface
Jimmacle
Jimmacle10mo ago
if you expect the cast to succeed, use a C style cast instead of as so you get an invalid cast exception if something unexpected happens
Pdawg
PdawgOP10mo ago
Okay Well
Jimmacle
Jimmacle10mo ago
that will give you more info than it just returning null
Pdawg
PdawgOP10mo ago
if (typeof(IPlugin).IsAssignableFrom(type)) it never gets past here though This is before the cast can be done
Jimmacle
Jimmacle10mo ago
then the cast isn't failing
Pdawg
PdawgOP10mo ago
It thinks that you can't cast PluginRoot even though it implements the interface properly
br4kejet
br4kejet10mo ago
Are you sure it's even processing your plugin's dll?
Pdawg
PdawgOP10mo ago
I believe so, when I tried debugging, the module showed up along with its respective Types
br4kejet
br4kejet10mo ago
Set a breakpoint on the LoadFromAssemblyPath line, and set a breakpoint on the typeof(IPlugin).IsAssignable... line with a condition of type.Name == "PluginRoot" And then check the debugger local variables for the type and see if it's correct
Pdawg
PdawgOP10mo ago
Okay. Also, I tried the C Style cast and got a generic exception out of it:
No description
br4kejet
br4kejet10mo ago
Maybe there's a version difference since you compiled the PluginRoot and the CLR doesn't like it
Jimmacle
Jimmacle10mo ago
do you have multiple types called IPlugin?
Pdawg
PdawgOP10mo ago
nope, just one trying this rn
Pdawg
PdawgOP10mo ago
@br4kejet
No description
Pdawg
PdawgOP10mo ago
This next breakpoint is never hit
No description
br4kejet
br4kejet10mo ago
If you move next then it should try to run CreateInstance or you could do that
Pdawg
PdawgOP10mo ago
It just fails at the if statement, it thinks that the PluginRoot isn't assignable to IPlugin It won't run the CreateInstance
br4kejet
br4kejet10mo ago
No description
br4kejet
br4kejet10mo ago
Click the little arrow thing on type
Jimmacle
Jimmacle10mo ago
are you absolutely 100% sure there aren't multiple types in your project called IPlugin?
br4kejet
br4kejet10mo ago
Explore the interfaces
Jimmacle
Jimmacle10mo ago
because what this is indicating is the IPlugin you're testing against and the IPlugin the type implements are different types
Pdawg
PdawgOP10mo ago
No description
Pdawg
PdawgOP10mo ago
I'm certain that they're implementing the same interface
Pdawg
PdawgOP10mo ago
No description
Pdawg
PdawgOP10mo ago
PluginRoot implements GyroShell.Library.Interfaces.IPlugin
br4kejet
br4kejet10mo ago
I dunno then, the code I gave worked for me Though I use an abstract class instead of an interface
Pdawg
PdawgOP10mo ago
should I do that instead?
br4kejet
br4kejet10mo ago
Could try it
Pdawg
PdawgOP10mo ago
It doesn’t really matter which method I use, as long as it’s not some crude manual reflection thing
br4kejet
br4kejet10mo ago
Then if that works try using an interface again
Pdawg
PdawgOP10mo ago
I’ll try an abstract later, I gotta go eat dinner Thanks for the help though
Jimmacle
Jimmacle10mo ago
dunno if it'll help but here's relevant code from the last plugin loader i was involved with https://github.com/TorchAPI/Torch/blob/master/Torch/Plugins/PluginManager.cs#L506-L573
Pdawg
PdawgOP10mo ago
Cool, I’ll look into it later. Thanks! @br4kejet Hey, I'm back, and I tried an abstract class same problem as before I'll check the version of .NET and WASDK Nope, they're on the same version of WASDK and .NET oh wait what i just fixed it for some reason, when the assembly loader attemped to load the file, it was also loading the reference library. i thought that was the issue earlier, but i fixed it at the wrong spot. the issue needs to be fixed before the file even loads
Pdawg
PdawgOP10mo ago
No description
Pdawg
PdawgOP10mo ago
it's working now weird behavior nonetheless but hey it works 🤷
Pdawg
PdawgOP10mo ago
No description
Pdawg
PdawgOP10mo ago
there we go
Want results from more Discord servers?
Add your server