简体   繁体   中英

Reference a DLL from another DLL

I have a C# application program, let's call it App.exe. It references a DLL named A.dll which in turn references another DLL, namely, B.dll. However the way in which they are referenced is a bit different. In the code of A.dll, it has directly referenced B.dll (by going to Project > References > Add B.dll). However my App.exe has code to load A.dll at runtime using Assembly.Load() etc.

So to recap,

App.exe ---- (runtime loading) ---> A.dll ---- (direct reference) ---> B.dll

All three things (App.exe, A.dll and B.dll) reside in the same directory, let's say ExeDir. Now what I want to do is, put A.dll and B.dll in a sub directory of ExeDir. I can do this by using an App.config file that specify the path of A.dll and asking the App.exe to load A.dll from that path. So far so good.

However the problem is that when I do this, .NET gives me an error saying that it cannot find B.dll which is in the same directory as A.dll. If I move it back to the original directory (the same directory as App.exe) then it works fine. Which means, I can put A.dll in a sub directory, but the B.dll needs to be in the original directory.

Is there any way in which I can keep both DLLs in the sub directory?

Add a <probing> element in your app.config:

http://msdn.microsoft.com/en-us/library/823z9h8w.aspx

<configuration>
   <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
         <probing privatePath="bin;bin2\subbin;bin3"/>
      </assemblyBinding>
   </runtime>
</configuration>

You can manually resolve the B.DLL assembly by providing an event handler to the AppDomain.AssemblyResolve event of the current AppDomain.

currentDomain.AssemblyResolve += ResolveLostAssemblies;

Then provide an implementation of ResolveEventHandler :

private Assembly ResolveLostAssemblies(object sender, ResolveEventArgs args)
{
    // Find the assembly referenced by args.Name, load it dynamically, and return it.
}

I've found that this provides the most control over which assemblies get loaded and when. It especially works well in the situation where you're application is pluggable and each plugin lives in their own subdirectory of a "plugins" folder (which isn't necessarily the application directory). Technically the assembly doesn't even have to be a physical file using this method. Though D Stanley's method is generally considered more standard.

One option is to try registering your assemblies in the Global Assembly Cache. http://msdn.microsoft.com/en-us/library/4a9t8a9a.aspx But it's probably not preferable to D Stanley's answer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM