I have a program which needs to use a large number of plugins.
Each plugin must support a very basic interface, this interface is defined in a DLL (IBaseComponent for simplicity of question sake).
Each plugin will be in a specific directory (AppDirectory\plugin\plugin-type). Each plugin can have any name for the plugin's dll (AppDirectory\plugin\plugin-type\plugin-name.dll).
So I need to check through each plugin subdirectory, find each plugin that has a class which supports the IBaseComponent interface, instantiate the class and call some functions on the plug in.
ok, all fine and dandy, none of this is particularly hard. The problem though is that I seem to be running into some weird issues.
Every plugin needs to have the Base.dll file in the individual plugin folders (instead of just in the program that will be loading the plugin) and also it seems that I get many errors and warnings around dynamically loading a dll which have dll's that also need to be loaded.
I'm using:
pluginModule = System.Reflection.Assembly.ReflectionOnlyLoadFrom(PathToAssembly);
in order to grab the plugin dll and using:
types = moduleAssembly.GetTypes();
in order to grab the types contained within the dll. I am iterating over the types and checking if the individual type is of the IBaseComponent interface (signifying this is a valid to load class) with:
if (type.GetInterface("FrameworkNameSpace.IBaseComponent") != null)
//it's of the IBaseComponent interface
Later, in order to actually create an instance of the class from the dll I use:
pluginModule = System.Reflection.Assembly.LoadFrom(PathToAssembly);
and then use:
types = component.GetTypes();
In order to get the types within the module then select and load the class which supports the interface same as above.
The problem seems to be on when I use:
types = component.GetTypes();
When actually trying to load the class, Instead of simply looking at it. (Hence my different usage of LoadFrom and ReflectionOnlyLoad)
The Exception I receive on the GetTypes call (on a second plug in, but never the first!) is:
{"Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information."}
With the LoaderExceptions property as:
{"The specified module could not be found. (Exception from HRESULT: 0x8007007E)":null}
I'm unsure why this occurs. The DLL is in the plugin folder, and the DLL containing the IBaseComponent interface is also in every one of the plugin directories. Am I going about this the wrong way?
Also is it required for me to keep a copy of the DLL containing IBaseComponent within each plugin subdirectory as well as the one used by the program itself, or am I doing something incorrectly that w开发者_运维问答ould allow me to remove this requirement?
I am aware of MEF which is what I wanted to use but unfortunately because I am required to support this on .net 2.0 I am unable to use MEF.
This is a LoadLibrary() failure. Sounds to me that you plugins have a dependency on some unmanaged DLLs. Yes, Windows is going to have a hard time finding these DLLs, it has no reason to look in the plugin directories. Maybe it works the first time because your app's default directory happens to be set to the correct directory. Which would then also be the workaround, use Environment.CurrentDirectory.
Finding out exactly which dependencies can not be found is key. Unmanaged ones are not going to show up in fuslogvw.exe, you can dig it out of a trace from SysInternals' ProcMon utility.
精彩评论