Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic loading of DLL

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 would 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.

like image 558
Script and Compile Avatar asked Feb 25 '11 21:02

Script and Compile


People also ask

What is the purpose of dynamic loading?

Dynamic loading is a mechanism by which a computer program can, at run time, load a library (or other binary) into memory, retrieve the addresses of functions and variables contained in the library, execute those functions or access those variables, and unload the library from memory.

What is DLL loading?

The DLL. Load method loads a particular dynamic link library in TestComplete and returns a pointer to the library. Later, this pointer can be used to call routines from the dll. Before you load a dll, you should define its type and type of its functions using the DLL.

Is Delphi static or dynamic?

Delphi has several different kinds of arrays: static arrays, dynamic arrays, and open arrays: A static array is a traditional Pascal array. You can use any ordinal type as an index, and an array can have multiple indices. The size of a static array cannot change at runtime.


1 Answers

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.

like image 68
Hans Passant Avatar answered Sep 18 '22 12:09

Hans Passant