After refactoring a WCF service, the service throws an error saying that it can't find a library that it's no longer supposed to use. The reference to the DLL has been removed from the projects' references, it's not in the config files, and looking through the XML of the .csproj files, there's no artifact reference. The solution has also been cleaned and rebuilt multiple times, the IIS server on which it's running has been restarted, its app pool recycled, and I even found the .cache files in the Debug folder and yet, the app is still complaining that it can't find the DLL it's no longer supposed to use.
Where else could a reference possibly be hiding and what can I do not to have to re-assemble the service file by file, project by project, or calling some sort of .NET exorcist to ensure that the offending DLL isn't there anymore?
Related
I have a remote SQL Server database, wrapped with Entity Framework inside a dll.
When I reference that dll from my main application, I get a runtime exception stating "missing connection string in app.settings file" or, if I manually add the connection string, "no Entity Framework engine found".
If instead, I install EF from NuGet ALSO in my main application, the referenced dll works perfectly.
Now, the reason why I created and referenced the dll was to detach my business layer from the persistence layer, but if I need anyway a reference to EF for my application to work, I'm loosing the advantage of the dll wrapping.
What should I do?
EDIT:
I can't add a dependency from my main app to EF simply because the user of that dll will be a client outside .NET, such as an Excel or Matlab instace
You will have the same issue with all your dependencies. You must distribute multiple DLLs and make sure they get loaded. See
See Resolving Assembly Loads
The AssemblyLoad event allows you to take over the assembly loading process for your AppDomain, and you can find the dependent assemblies on disk outside of the normal search locations (which are dependent on the host .exe location), or download them, or unpack them from assembly resources in your main .dll.
See also How to load an Assembly in a SSIS script task that isn’t in the GAC
The dll NEVER has it's own config file that it accesses to read settings such as connection strings. Although your code to read the config information may be in an assembly, the config file is owned by the host process, so an entry for connection strings MUST be present in the Host processes config file.
In your scenario, it sounds like on the remote sever it will be SQL server that acts as the host process. On your local machine, the host process (your .exe or website, IIS Wp3 ) will act as the host process. Your local process WILL require the connectionstring setting in web.config / app/config.
In VS, when we add a reference to an assembly project, all of the dependent .dll's get compiled and placed in the top level applications bin folder. If you simply reference a .dll file from your application, these dependent .dll files are not placed in the bin folder. This is what you are experiencing here with EF.
It is possible to encapsulate EF functionality inside a .dll file, but the .dll files which make up EF itself, MUST be available to the host process. You don't need to add a NuGet reference to your main application. By referencing the project that you .dll is built from in your main application, the EF engine will be compiled to the bin folder of your main application.
Once you have built and deployed your main application with a project reference to your assembly, all the required files will be in the folder from which you execute your application. You can then make changes to the .dll source and just update the .dll binaries in the application folder, providing the changes do not break contracts etc eg. method signatures.
I have been given a web service project to work on and I've made it reference a dll. This dll has several other dll's it is dependent on to load. For any other application I've used that needed this dll, I just slapped the dependent dll's in the bin folder. This doesn't seem to work for the web service application, and I get the error stating that "blah.dll failed to load because dependent dll blah blah". My question is where can I put these dependent dll's or what can I configure in visual studio for the web service to find and load the dependant dlls.
Thank you.
*Also, this is for debug purposes only, so the solution doesn't need to be the "correct" way. Anything hacky is fine, as long as I get it to work.
I recommend that you enable the "Copy Local" option on each reference to a non-standard dll. This will ensure that the dlls are copied into the bin directory when you build, and you can easily build a deployment from there. Assuming you are hosting under IIS, it should be as simple as zipping up the bin directory and moving it to your server application directory.
I have created a build task in vs2012.
I ran it.
It complains that there are some missing references,
though I see them on my proj and they lead to relative path
(the folder that exists in the source control)
I have ereased the sln locally,
I did get latest from the source control and rebuilt it.
The references were missing. I have fixed it. Re-run the taks and again similar error.
How can it be if the sln builds successfuly on my machine and on a colleage clean machine?
If I had to take a guess, it would be one of the following:
The missing types are located in one or more assemblies that are either not checked into source control; or
Those assemblies are referenced via a path reference that isn't the right path in your source control.
Those assemblies aren't part of the normal project structure that would be pulled down by the build server.
Those assemblies are gac'd locally and you are referring to gac'd versions instead of the correct ones.
It's a web site project and someone on your team has those assemblies gac'd or installed in some other directory and they screw up the project every time they check it in. (common in web site projects, highly unusual in web application projects).
I have a weird situation with some code that I inherited at work. Their application is a multi-project solution, with several of the solutions being (code) pieces of the MS Enterprise Library (not sure which version).
They also have an existing C++ (unmanaged) application which has a bunch of DLLs. One of these DLLs is built in a separate solution, both in 64-bit and 32-bit flavours.
The main application has a reference to this DLL, and calls a couple of static functions (I can see intellisense, even). I can compile and build the main application EXEs, but when I run it, I get an exception that this DLL from the unmanaged code (lets call it CPlusPlusCode.dll cannot be found:
FileNotFound Exception was unhandled: Could not load file or assembly 'CPlusPlusCode.dll' or one of its dependencies. The specified module could not be found.
I'm quite stumped, because I can compile the code, see intellisense for the imported classes, and dig into the DLL in the object browser. I even made sure there's a copy in the \bin\Debug folder (although I don't see why that would make a difference). This is for a Windows Forms application.
Also, if it matters, I had some build issues related to x86 vs. x64 for different projects; I think (hope?) that this is not related to that, but I solved that by using the Configuration Manager to build everything as x64.
Check the GAC, and if necessary you might need to add it or register the DLL there.
I had this problem with a project, it all works ok from Visual Studio and most of my times running the project locally on my machine. But because of the unmanaged code I needed specifically allow the project to be executed with correct permission levels.
So have a look in the manifest file, that enough permissions etc exist.
I have created a dll that will be used by multiple applications, and have created an installer package that installs it to the program files, as well as adds it to the Global Assembly Cache.
The dll itself uses log4net, and requires a xml file for the logging definitions.
Therefore when the installer is run, the following files get copied to the install directory within program files:
The main dll that I developed
- The Log4Net.dll
- the Log4Net.xml file
I am now experiencing a problem. I have created a test console application for experimentation. I have added my dll as a reference, and set the 'local copy' flag to false.
When I compile the test console exe however, I noticed that it has copied the log4net.dll and log4net.xml files to the bin directory. And when running the test console, it appears that it will only work if the log4net.dll is in the same directory as the exe. This is dispite the fact that the test console application does not use log4net, only the dll that was added as a reference does.
Is there some way to have it so that the log4net.dll & xml files used will be the ones that were installed to the program files, rather than any application needed to copy over local copies? The applications that will be using my dll will not be using log4net, only the dll that they are referencing uses it.
Many thanks
Don't install into the Global Assembly Cache! Even if your library dll is used by multiple applications each should have it's own local copy. Otherwise you get into a whole world of pain for saving a few KB of disk space.
Always copy the required dlls locally. If you are really sure that the application won't need it you can simply delete the unnessesary dlls later or don't include them in the installer. But if your application will call ANY reference there it will crash at runtime. So best option is to leave them there (after all they WERE referenced for a reason).
No, it's not possible (at least not without much efford) to have .Net load dlls from arbitrary locations on the disk. And it should be this way (look up DLL-hell if you want to know why).
I suspect your problem is the configuration. You must use fully qualified names if you want it to work from the GAC. As per the documentation at http://logging.apache.org/log4net/release/faq.html:
"When loading an assembly from the GAC the fully qualified assembly name, including the version, culture and public key must be specified. This is in the standard syntax supported by System.Type.GetType. See the next FAQ on how to get the version and public key for an assembly."
I managed to resolve this by adding Log4net.dll to the GAC as well. It will now run without needing a local copy the dll.
It does however require a local copy of the XML file, to correctly log.