Reference a DLL from another DLL

2019-02-02 15:08发布

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?

标签: c# dll reference
3条回答
戒情不戒烟
2楼-- · 2019-02-02 15:21

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.

查看更多
等我变得足够好
3楼-- · 2019-02-02 15:21

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.

查看更多
对你真心纯属浪费
4楼-- · 2019-02-02 15:25

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>
查看更多
登录 后发表回答