Could not load file or assembly or one of its depe

2019-02-28 19:59发布

问题:

I have the "Main" program which loads my own "plugin.dll" file dynamically using reflection. The "plugin.dll" file references to the third party "device.dll" by using visual studio references. As long as the "device.dll" and "plugin.dll" are in the same folder as the "Main" program or the "Main" program has the reference to the "plugin.dll" everything works fine. But as soon as I move the "device.dll" file to another folder I get the following error message: "Could not load file or assembly or one of its dependencies. The system cannot find the file specified." The problem occurs because the program does not find the "device.dll" file. The "Copy Local" property or the "Reference paths" does not have any effect towards this issue. I understand that I have to specify the path to the "device.dll" but I could not find a way to do it without putting the "plugin.dll" and "device.dll" to the GAC (global assembly cache). GAC is not a solution because third party dll has to be strong-named as well (dissasemble and assemble again), which is not allowed by copyright license.

Additional details: Using visual studio 2013 and .Net framework 4.0 FUSLOGVW does not register any errors (any ideas why?).

Looking forward to your suggestions, thanks in advance.

回答1:

Check the AppDomain.AssemblyResolve event. It's the ideal point where you may peform a custom action to load an assembly in a non-default location.

I add here a quote of linked MSDN article:

It is the responsibility of the ResolveEventHandler for this event to return the assembly that is specified by the ResolveEventArgs.Name property, or to return null if the assembly is not recognized. The assembly must be loaded into an execution context; if it is loaded into the reflection-only context, the load that caused this event to be raised fails.

At the end of the day, this means that your application or service will enter into the AssemblyResolve event case when an assembly couldn't be loaded using default assembly discovery approach (AppDomain.BaseDirectory, Global Assembly Cache...).

Once the so-called event is raised, you need to return an instance of Assembly and it's your job deciding how to load the assembly (from file, stream, bytes...). That is, if you're placing your plugin assemblies in some sub-directory or who knows where, you can call Assembly.Load with the right full assembly path to load them and avoid your assembly loading issues.