10

I've a working XML Web service written in ASP.Net. Now I need to reference certain assemblies lying in a specific folder e.g. c:\NotMyCode
I do not want to copy/duplicate zillions of dlls in that folder into my bin folder.

I tried to keep the CopyLocal=false for the assemblies referred in the Web Service. That ended up in a FileNotFound exception for the assembly. When I switch to CopyLocal=true, the referenced DLLs are copied over to the bin folder.. and it works.

So my question here is: How do I reference assemblies that do not lie in my bin folder or a subfolder beneath it ? Do I need to change some security policy files somewhere? I think I'm not the first person to ever want to do something like this.. so I'm assuming someone has already solved this problem.

(I've tried impersonating an admin user in the IIS ASP.net configuration panel, but that didnt work either.)

Update: Can't install it in the GAC either. To give an analogy, this web service is giving a simplified view to a third party app e.g. Starteam. I can't (shouldn't have to.. don't want to..) copy all the binaries in that folder to the bin folder or install it into the GAC

Kiquenet
  • 14,494
  • 35
  • 148
  • 243
Gishu
  • 134,492
  • 47
  • 225
  • 308
  • I am having the same problem and cannot find a solution! Have you managed to work around this ? I am using .NET 3.5. It seems like a similar bug to http://support.microsoft.com/kb/812832. – dtroy Dec 20 '10 at 07:17

5 Answers5

14

According to the MSDN documentation,

Referenced assemblies outside the application's root directory must have strong names and must either be installed in the global assembly cache or specified using the <codeBase> element.

So, it might appear that you're out of luck. Here's what I'd try:

  1. Create an NTFS junction point under your application base directory which points to the directory containing your shared code. This is the key step. For example, in your application base directory, run linkd SharedCode c:\NotMyCode. This makes <yourappbase>\SharedCode effectively be an alias for c:\NotMyCode.
  2. Tell ASP.NET to probe for assemblies in this path, using a <probing> element, referencing the junction point SharedCode. Since this is under your application base, it should work. Alternatively, use AppDomainSetup.PrivateBinPath to set the path probed for assemblies.

I'm quite curious to see if this works :-)

Matt
  • 74,352
  • 26
  • 153
  • 180
Vinay Sajip
  • 95,872
  • 14
  • 179
  • 191
  • +1 for sneakiness.. didn't know about linkd. It managed to fool Windows explorer but not ASP.Net. ASP.net copies the binaries to a temporary location from where it is executed. What is strange is that the temp location shows these files - however FusionLogVw does not show an entry for failed assembly resolution. But the server responds with a FileNotFound as usual... – Gishu Jul 31 '09 at 11:20
  • 1
    we can disable shadow coping to temporary directory.. but i don't like JUNCTION solution it is like hack...\ – Brans Ds May 31 '13 at 09:42
  • I tested probing it dosn't wokks for me with web development server - server jest returns internal error...assembly resolving don't helps server fails during starup – Brans Ds May 31 '13 at 09:43
4

You could always use the: AppDomain.CurrentDomain.AssemblyResolve Event and call

Assemly.Load(Path.Combine(@"c:\NotMyStuff",args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll"))

See link for more info.

coding4fun
  • 8,038
  • 13
  • 58
  • 85
0

You could always put your referenced assemblies in the GAC, then the location would not matter. You can install the component by dragging it into the GAC (C:\windows\assembly) or running GACUtil.exe.

This article may help. It describes the "Best Practices for Assembly Loading."

At first I thought you could used the <probing privatePath="bin\debug"/> element in the runtime/assemblyBinding in the web.config, but the probing will only allow you to specify subdirectories under the root location.

Mike Ohlsen
  • 1,900
  • 12
  • 21
0

I think you can reference specific assembly paths in code as well.

AppDomain.CurrentDomain.AppendPrivatePath("C:\\NotMyCode");

Doing that in your Global.asax Application_Start should do the trick.

davewasthere
  • 2,988
  • 2
  • 24
  • 25
  • AppendPrivatePath is obsolete, according to MSDN: http://msdn.microsoft.com/en-us/library/system.appdomain.appendprivatepath.aspx – Vinay Sajip Jul 30 '09 at 14:06
  • That must have been in 3.5.. Am still heavily 2.0 unfortunately. PrivateBinPath then.... Same same... – davewasthere Jul 31 '09 at 16:25
-1

You can put in GAC and access it from there.

Bhaskar
  • 10,537
  • 6
  • 53
  • 64