An episerver installation puts the episerver assemblies in the GAC, I see them with C:/windows/assembly.
Besides, all the episerver dll's are present in C:/Program files/Episerver after an episerver installation.
When a create an episerver project via the episerver deployment center or with Visual Studio 2010 using the episerver template, I see that the bin-folder of the newly created project contains a lot of episerver-dlls, which is not very surprising. And I suppose that they are copied from C:/Program files/. If I open the project in visual studio, I see that it's those dll's that are referenced and not the ones from the GAC or from C:/program files/episerver.
Well, all of this is very confusing.
Why is Episerver putting dll's in the gac and not referencing them? What is the best way to handle references to episerver dll's for development in a team?
Moreover, IF episerver would reference the ddl's from the GAC, how would I see that in VS. I mean, what would the properties of the reference be?
Basically, this is all just episerver deployments decisions. I'll try and go over every your question one by one:
Putting dlls into GAC is useful when you want your users to access dlls in the reference dialog from ".NET Framework" tab. Suppose you're creating simple project (not episerver one) and want to add episerver dlls. Instead of looking for them on the hard drive you reference ones that are pointed from the GAC. That's easy for development.
Why not reference GAC dlls ? It's to easier deploy your solution with the dlls. Suppose you're deploying your solution to the server. Server won't be having episerver dlls in the GAC (and shouldn't have, anyway). So they're probably setting "copy local = true" property to copy the dlls into the output folder, making your solution portable. Also, the GAC assemblies aren't "referenced" - GAC just contains copies in a case of need and a reference is added to the "program files" folder with the dlls.
Best way for a development team is to use GAC or to define some kind of "Third Party"("externals") folder in the repository and put your dlls there (and reference from there). First approach requires episerver install on every dev machine, second uses up some space in your repository.
As GAC assemblies can't be referenced (they actually can be, but it's a headache), there is virtually no difference between the result - different paths only.
We usually create a separate directory where we store all .dll-files and reference them from that directory. This means all third party-librarys and episerver-dlls.
The biggest reason for doing this is to avoid a hassle when a new developer needs to setup the project, and also to avoid conflicts between different versions when referencing from GAC.
Related
Backgroud:
I am in the process of migrating a console application to be part of our existing web API project. All development work is done on Visual Studiod 2015 (with IIS Express). The application uses few third party datasource api DLLs to grab data from that datasource. All these DLLs are managed by our internal nuget package sources.
Issue:
Now the console application runs fine and can load up the those DLLs. I copied across the logic into my web project and added the DLLs via nuget. Solution builds but got the following error when starting up the web project:
Could not load file or assembly 'ABC.DLL' or one of its dependencies. The specified module could not be found.
Where ABC.DLL is one of the third party DLLs.
I have done the following:
Confirm ABC.DLL is in the bin folder of my web project
Changed target build platform of my web project to be x86 and unchecked "Use 64 bit version of IIS Express for websites and project" setting in VS2015 (the third party dll is 32-bit)
Ran dumpbin.exe on ABC.DLL's dependency and got XYZ.dll,MSVCR120.dll,KERNEL32.dll,MSVCP120.dll,mscoree.dll
Regarding to the last step, those dlls were all missing in the bin folder (but the last 4 DLLs should be in system32 win directory so shouldn't matter?)
As for XYZ.dll, it is another third party library and is located on C:\Program Files (x86)\XYZ\ folder. I manually copied it across to the web project bin folder (in fact copied across all Dlls inside XYZ folder) and still get the same issue.
Questions
What am I missing here? The console app obviously can load ABC.DLL but the web project can't. Appreciate it if you can tell me what to check next.
The error message from start up web page is not very useful, is there a way to find out where the web project is trying to load the third party DLLs?
Thank you in advance!
Simply adding external DLLs to your Bin folder is not a great idea. Files can disappear from this folder for various reasons, such as your team members deleting a seemingly useless DLL, or through Visual Studio clearing it. Also, the output DLLs from referenced projects in your solution, would end up there, and are replaced every time you build your project.
What you should do for third-party DLLs, is create some "dependencies" folder in, or close to, your project, and stick the DLLs in there. Then you should right-click on the project, select Add Reference, browse to that new "dependencies" folder, and add a reference to the DLL that way. This is similar to the way NuGet works; it keeps DLLs in their respective folders inside the packages folder, and adds references to those DLLs.
I finally found the issue and thanks for all the help, I had to disable shadow copying in VS (mentioned in 64 bit managed assembly with unmanaged dependencies not loading in IIS / ASP.NET MVC 4).
I have a bunch of assemblies (DLLs) I want to reference in my current .NET 4.5 project. However, right now all of them sit in some local folder in my Hard Drive. When someone works on this same project, these reference assemblies obviously aren't in the same local folder. My plan is to copy these assemblies into some folder in my project, and put that in source control.
Is this a good plan? And what folder do these things usually go to?
NuGet is a prefer method; however, some assemblies are not in NuGet. So here is an example what nopCommerce does.
Create a Dependencies folder (inside your project folder)
Keeps all third parties assemblies inside it.
Definitely a good idea. Generally I'll have a "dependencies" directory at the top level of the solution (or one higher if you have one), with all the DLLs that the projects use. Those are in source control, so when you check the code out, it will just work as-is, since the DLLs are all relative to the projects.
NuGet is the most common way to use external libraries and it places the dependencies in a folder called Packages at the root of the solution folder. You can create a folder called dependencies for your non-nuget dependencies. By placing this folder at the root of your solution you can make relative references so that works for everyone.
Better way to GAC all the DLL assemblies.
http://msdn.microsoft.com/en-us/library/ex0ss12c(v=vs.80).aspx
gacutil -i "DLL File Path"
I know not to put strongly named assemblies into the bin folder on early versions of ASP.NET. I remember this caused problems, but I don't remember specifically what problems. Does anyone know if this still applies to ASP.NET 2.0? Is there any reason not to put strongly named assemblies into the bin folder on ASP.NET 2.0 or later versions?
The problem you describe was fixed on .NET 2.0, so you don't need to worry about it anymore.
However, beware that if you put a strong-named assembly in the bin folder, and an assembly with the same strong name exists in the GAC, then the assembly in the GAC will get loaded.
There should be no problems with this. I've done it a few times during development/testing and I even have a site currently running that has strongly named assemblies in the bin folder with no issues.
Assemblies are strongly named for a reason (obviously) so you should have a good reason to drop them in the bin folder.
I have not experienced problems with strong named assemblies being put into the bin. I have experienced some Interop problems with strong named assemblies and versioning conflicts, but those were caused by developers compiling older versions of an ComPlus application library into the solution instead of the current or newer version.
I used Dotfuscator to protect my application from reverse engineering I encrepted the dll files and saved them, my question is what to do after that? how to use new dlls insted of old ones because when i do copy and past and after that I publish the website it get the old dlls not new ones?
Are you publishing your site via Visual Studio? If so, it would seem that the obfuscated DLLs are somehow bypassed. Are you overwriting the original DLLs with the obfuscated DLLs before publishing them? As a last resort, use FTP to publish your site, as you can be sure which versions of DLLs you're uploading.
We have a web application that's deployed to many websites with only frontend changes, the shared backend portion has it's DLL in the GAC so we only have to update that one dll and all the sites get the update.
Is there a way to override the GAC with a DLL in the /bin folder to test out new features before they get released?
If it has the same version number as the referenced DLL, the GAC gets used.
If you increment the version number, rebuild the website referencing the new version number, put the new version in the /bin directory, then that DLL will be used.
If you do not want to change the version number, you're pretty much out of luck.
When .NET loads strong named assemblies, first it tries to decide what version number to use. It does this via the reference first, then it looks for publisher policies, then it looks for binding redirects in the configuration file.
After it does this, it looks for the assembly in the GAC, then in any codebase specified, then it probes various file system folders for the DLL. If at any one of those steps it finds the right version assembly, it stops.
If you are not changing the version number of your strong named assembly, .NET will find the original one in the GAC and stop looking. Note that because it stops when it finds one, and because looking in the GAC is first, specifying a codebase for your assembly will do no good unless you also specify a new version number.
I have been able to override the GAC with the assembly in the \bin folder using the <codebase>Element.
By specifying <codebase version="1.2.3.4" href="/bin/MyAssembly.dll" /> in my web.config file I can tell my application to use this version rather than the version specified in the GAC.
You may also want to take a look at the <probing>Element for specifying assembly locations?
I think I might be saying the same think as Adam Sills, but re-worded it for my understanding. Through my own testing, looks like this is what happens:
If your app is compiled with version 1.0.0.0 and 1.0.0.1 is in the GAC, then you can omit the .dll from your /bin.
If your app is compiled with version 1.0.0.1 and 1.0.0.0 is in the GAC, then you MUST place the .dll in your /bin to ignore the GAC. A error will occur if the GAC version is older than the required version of your app, unless you include the newer version in your /bin.
I hope this is correct...
You can view binding information in the log file using the Assembly Binding Log Viewer (Fuslogvw.exe), which is included in the Windows Software Development Kit (SDK).
s