Reputation: 3904
I'm working on a project with a plugin like system. The project structure is defined as follows:
- Solution
- Project A (Cli)
- Project B (Core logic)
- Project C (Plugin)
Project A
is the startup project, Project B
contains the core logic and Project C
is a plugin, which implements an interface in project B
. Project A
only has a reference to Project B
and Project C
only has a reference to Project B
.
Since I do not reference Project C
from Project B
(and do not instantiate the class directly), code like AppDomain.CurrentDomain.GetAssemblies()
(inside Project B
) does not return Project C
.
However, once I do (from Project B
): var MyImplementation = new MyImplementation()
, AppDomain.CurrentDomain.GetAssemblies()
does return the assembly, since it's known and loaded at runtime as I instantiated the class MyImplementation
explicitly from code.
From Project B
, I want to get all assemblies which implement a specific interface from Project B
and instantiate them.
So, how do I get these (seemingly) unknown assemblies to get loaded at runtime?
Upvotes: 0
Views: 330
Reputation: 93
I don't think it's possible to know if an assembly contains a class that implement your interface without loading it.
What you can do is provide a directory where you put all your plugins assemblies.
So you can load your plugins in your AppDomain like this :
public static Assembly[] MyPlugins { get; private set; }
public static void LoadAssemblies()
{
MyPlugins = Directory.GetFiles(lookingDirectory, "*.dll")
.Select(assemblyPath =>
{
AssemblyName an = AssemblyName.GetAssemblyName(assemblyPath);
return Assembly.Load(an);
})
.ToArray();
}
And then you can find all types that implements your interface like this :
MyPlugins.SelectMany(assembly => assembly.GetTypes())
.Where(type => typeof(IYourInterface).IsAssignableFrom(type))
.Select(type => (IYourInterface)Activator.CreateInstance(type))
And then you can iterate on each implementation of your interface to call a shared method for example.
Upvotes: 1