Dynamically add .dll into web application - asp.net

I need to add assembly into my asp.net application whithout local copy to bin folder, without adding it to GAC. It should be path-reference like C:\bin and this folder is not subfolder of application. Does anybody have suggestions?

You can use reflection for that:
System.Reflection.Assembly assembly = System.Reflection.Assembly.LoadFrom("path here");
With the assembly instance, you can execute methods on the fly and pretty much do everything.
Also worth noting that with ASP.NET you run as a different user with less privileges in the operating system, so proper permissions have to be set over the folder where the DLL is located.

Related

Which dll files of ASP.NET web application does IIS load?

I couldn't find any information about it. Does anybody know whether IIS load all dlls in bin directory of web application or all dlls in any directory or maybe only directories referenced by project (in this case how it determines which dll is "master")?
I've just had a situation where someone didn't remove all files from web application directory before deploying new version, while some dll was renamed. This redundant dll was in bin directory of MVC 4 web application.
As an experiment I made a new ASP.NET Webforms project, and deployed it to IIS. I then made a 2nd .net class library, and copied the .dll file to the web app's \bin folder (the class library is not referenced or used anywhere in the ASP.NET app).
I started up SysInternals ProcMon, recycled the app pool and web site in IIS, and requested the site in a browser.
w3wp.exe does indeed read the class library .dll file on first page request.
This MSDN page also states:
You can store compiled assemblies in the Bin folder, and other code anywhere in the web application (such as code for pages) automatically references it. A typical example is that you have the compiled code for a custom class. You can copy the compiled assembly to the Bin folder of your Web application and the class is then available to all pages.
Assemblies in the Bin folder do not need to be installed in the Global Assembly Cache (GAC). The presence of a .dll file in the Bin folder is sufficient for ASP.NET to recognize it.
Which does seem to imply that ASP.NET will reflect over the assemblies it finds in \bin and automatically load them.
Interestingly, even if you put a non-.net file (I copied twain.dll from C:\Windows) into your ASP.NET bin folder, those files are also read. The runtime seems to just ask the filesystem for \bin\* and loops over the files to check for .NET assemblies to load.
I also noticed that if you add this to your web.config file:
<system.web>
<compilation targetFramework="4.5">
<assemblies>
<clear />
</assemblies>
</compilation>
Then the page will no longer run, with the error
Could not load type 'WebApplication1.Global'.
So it seems that the runtime no longer loads those classes from the assemblies. However, the runtime still reads the non-referenced console application .dll and non-.net assembly twain.dll off the drive.
So, the answer comes down to what you mean by "loads all dlls" ... If you mean makes available in the runtime, then the answer is sort-of "no" if you specify your own system.web | compilation | assemblies but the default is to load all. But if you mean what files are physically read, then "yes".
It doesn't load any DLLs automatically.
Every DLL it loads is directly related to a request. First, Global.asax is compiled (which may load some DLLs from bin). Then, whatever HTTP modules and HTTP handlers are defined in web.config (there's some overlap with the previous step). Then the final aspx/asmx/... Some others might go for the ride as part of the configuration or something like that, but all the DLLs that are loaded are always loaded explicitly.
Thus, there is no "master" DLL. web.config, Global.asax and the actual requested file are the ones to decide what's actually going to happen. If you need to have a particular DLL loaded (and you don't simply have it referenced), you need to do it yourself.
EDIT:
Since this is a bit complicated, let me expand a bit.
The main thing to keep in mind here is that ASP.NET is always dynamically compiled - at least to an extent. At the very least, you always have to compile Global.asax - no way around it. Now, dynamic compilation in ASP.NET has an important feature - it's out-of-process (at least for the legacy compiler - I'm not sure about Roslyn+). So whatever the compiler does to find references etc., doesn't actually reflect what's loaded to the worker process itself - and to your application domain in particular.
The dynamic compilation is handled by the BuildManager class on the .NET side - http://referencesource.microsoft.com/#System.Web/Compilation/BuildManager.cs,fb803c621f3806a8. Since you asked about a "master DLL", the most relevant bit would be the code that handles Global.asax compilation, which is one of the starting points of any ASP.NET application. The very initial compilation is handled by the EnsureTopLevelFilesCompiled method. Looking through the code, you can easily see the first steps:
CompileResourcesDirectory();
CompileWebRefDirectory();
CompileCodeDirectories();
...
CompileGlobalAsax();
Most of this is slightly different for web sites vs web projects, as well as for pre-compiled sites, but we can pretty much ignore that. Now, the code isn't the simplest code in the world, but basically, it boils down to producing a bunch of assemblies - about one assembly per code directory. Again, this is done out of process - while the compiler has to load the binaries in bin, they are not necessarily loaded into the ASP.NET worker process. Instead, only the necessary references are actually loaded.
The main thing to take from this is that the dynamic compilation will indeed do a lot of resolving to help you (after all, you don't even know the name of the dynamic assembly where your types are compiled, so you can't specify it!) - but that doesn't mean that all the assemblies in bin are loaded in your ASP.NET application domain. The easiest way to check this is to add an empty assembly that isn't referenced anywhere to bin, and then print out AppDomain.Current.GetAssemblies - you will see that while the file was indeed touched during the compilation process, it wasn't loaded into the ASP.NET application domain. You need to bear this in mind if you ever try to implement some dynamic module loading in ASP.NET - you need to load those assemblies yourself.
You can tweak the way the compilation works in your web.config (especially the global one) - for example, by default, all the assemblies in bin are loaded for compilation purposes, but you can use the system.web/compilation/assemblies tag to cherry pick whatever you want.
Yes asp.net loads any dlls present in your bin directory .
I have recently written a blog on this as I ran into an issue with dlls which were not used in my project. Please refer this blog ,trying to discuss couple of other common scenarios as well.
Asp.net loads all dlls in the bin directory.

How to create and run an ASP.NET website in an installed application's bin directory

Our application is composed of mixed C# / managed C++ CLI / native C++ assemblies & DLLs.
We have a wrapper assembly that exposes the application's API.
FOR EXAMPLE...to create new console applications that use the API, you must reference that assembly, and also set the console application's output directory to the BIN directory of our installed application. ( due to the use of reflection, etc., everything must stay in the app's BIN directory and output to that directory, you cannot do a copy local of just the one assembly or nothing works )
My issue is when creating an ASP.NET web forms application (nothing to do with the console app), I would like to use that assembly, so I need the web application to "live" in our application's BIN directory.
When I try that errors occur due to ASP.NET trying to preload every single assembly in that BIN directory.
Can someone provide instructions on how to get this to work? I've spent hours now on every combination of referencing assemblies, copying them all, and trying to use LoadFrom.
Without seeing the construction of this it's hard but ...
Bin referencing
Create a web application and reference the necessary dll from the web site via bin references
Right click the web application, select the browse option and pcik the dlls you need to reference. Select copy local to true so you get the dll copied through to the web application so you aren't forever dependent on the console app being exactly where it needs to be in relation to the web app.
Not a solution I would necessarily go with though - it seems like the arcitecture of the system is a little off. Cross you have to bare etc...
OR
GAC referencing
the dlls that you need to reference from the console app - strongly name them and put them in the GAC (global assembly cache). Both apps will be able to see them then.
Copy over the dll
I guess there is another solution around adding a post build step to the console app that reruns a batch file that will copy over the dlls into the web app. I think that's going to be pretty much the same as the bin reference though really.
Probing element
You could use a <probing> element in your web.config to instruct the CLR to search for other directories for assembles (it normally just does the GAC and bin (a simplification to be fair is that) ). This is going to enable you to reference your API folder - but only if it is under your application path. Although someone here has used an NFTS junction to get around this.
More info here
In fact this answer gives a lot more detail about this kind of thing
How do I reference assemblies outside the bin folder in an ASP.net application?
And good luck

TFS 2005 version control DLLs in the bin folder?

I noticed that the DLLs in the bin folder for asp.net websites do not seem to be getting saved. When I goto a new computer and get latest I am missing the DLLs.
What is the correct way to fix this ? Should I create a seperate folder to contains all DLLs ? And then can I somehow tell my bin references to goto that folder to get the DLLs?
If you are using third party dlls, you should absolutley consider putting them into TFS...
If those dll comes from another project from the same solution, you should not put them into TFS.
If you use a base class library in multiple solution, I would consider using the build functionality that TFS offers. You can access your latest build from a network share (add this share as a trusted source) or directly access those dll files from TFS source control.
EDIT: you can always go back in time in tfs without having to save whats compiled....
You do not want to check your compiled .dlls in with your source control. If you have other dlls that are not directly compiled by your application then you should create a library folder in your directory structure that contains then, and check that folder in.

Where are Web Application Project Assembly references stored?

Where are assembly refernces stored for a web application?
In a Web Site, I see assembly tags written to the assembly node in the web.config when you add a reference. I am just curious as to how the Web Application Project makes the connection to get the correct local dll?
I manually add the reference and the application builds, but the dll is not imported into the BIN folder, and the assembly nodes are not created in the web config as they are in a Web Site. I do a solution search for the text 'assembly="SomeAssembly..." and no results are found.
I am just curious as I am trying to centralize updating assembly references as a 3rd party control vendor puts out hotfixes on a regular basis and we end up having to run around and update all the individual page refernces to the assembly. I was able to do this effectively in the Web Site project, but I am fairly new to Web Application Projects. Any advice or links would be appreciated. I guess I'm looking for tips on assembly & control reference management for ASP.NET Web Application Projects.
Like most Visual Studio projects, references are kept in the project.
There are two kinds of reference:
Project References are references to another project in the same solution. They look like this:
<ProjectReference Include="..\VBClassLibrary1\VBClassLibrary1.vbproj">
<Project>{045D7D9F-8E44-4C4B-95F8-620E86593C5B}</Project>
<Name>VBClassLibrary1</Name>
</ProjectReference>
File references are references to an arbitrary file on disk:
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
If you expand the References folder and click on a reference, then look in the Properties window, you'll see that both kinds of reference have a "Copy Local" property. For project references it defaults to true, for file references to false (though maybe that's only if the file is in the GAC). Changing the default adds:
<Private>False</Private>
Since the assembly was not imported to the BIN folder, and your application works, I assume that it is stored in the GAC (global assembly cache) and marked as "copy local=false" in the reference properties. You don't see the reference to the assembly in the web.config, since your code behind assembly - YourApp.dll (which is always created for web-applications), contains a standard assembly reference to that assembly. When you run your application it loads the assembly from the GAC.
Those "missing" dlls are probably in the Global Assembly Cache and are available to all .NET applications.
You can add control references to the pages/controls section of web.config, which will apply to all pages in the application.
I had the same issue, deleting .vs folder in the directory of the project solved the issue for me as it forced the recreation of .suo file which (though bite code) had reference to the web.config file in the wrong directory

ASP.net Bin directory - dll loading

I need to use a dll in my asp.net application. How do I load a dll not from a bin directory?
Perhaps I should mention that the application is a mixture of asp code and asp.net code.
so, when I develop it on my machine, I place a dll in the bin directory, but after I move the code to the live environment, I don't want to have a separate bin directory for every piece that's using asp.net.
All I am moving is .aspx and .aspx.cs files. Is there a way to load a dll NOT FROM /bin (specify it with "using" statement)? Looks like it automatically looks in the /bin....
You can either place the DLL in the bin folder of the root of your application, or install it to the Global Assembly Cache (GAC) using gacutil (which requires the assembly to be strong-named and signed).
I would just keep it in the bin.
.net app looks in the /bin of the project, and the GAC (Global Assembly Cache) where you put system shared DLL-s.
If your app is one .net app (configured in IIS as one app), but you have aspx files in subfolders, they should see the root /bin folder. i'd stick with keeping dlls in /bin, if that isn't several tenths of bins (which would mean that you have a problem with your app organization).
GAC and bin are the only usual options.
You might also be able to configure your other folder as an additional bin folder, but I wouldn't hold my breath — this is from 1.1 and you still need to be within the same vdir as the main application.
Simply add the other dll's directories to your path environment variable. Must restart asp.net process / visual studio for the change to take effect. Worked for me.
that's the thing: because it's poorly organized (its a mix of asp and asp.net) it's certainly NOT configured properly....I think it's best to have "10 thousands bins" for now.
Thanks guys!

Resources