Visual Studio unit tests throw MissingMethodException when assembly is in GAC? - visual-studio

My application contains a piece of code that executes inside of Component Services, so we need to register our business rules layer (and its dependencies) in the GAC. One of those dependencies is FooCore.dll, which contains classes and services visible to the entire app.
Everything was working fine, until I added a new method to a class in FooCore. Now, when I run my unit tests, any test that calls this new method throws a MissingMethodException, even if I update the GAC with the latest version of the assembly. The only fix is to remove FooCore from the GAC before running the tests.
I've tried the following things:
Rebuilt entire solution, refreshed stuff in GAC, then ran tests = failure
Removed and re-added FooCore assembly reference in test project = failure
Ensured that FooCore is set as "Copy Local" in properties = failure
What can I do to ensure that VSTS loads referenced assemblies from their explicitly defined location, rather than from the GAC?

Further research turned up this forum thread on this issue, in which someone suggests this might be caused by VS2008's Performance Analysis feature holding onto a stale version of the assembly.
I was able to solve my problem by:
Rebuilding my solution, then
Refreshing everything in the GAC, then
Removing and re-adding the assembly references in my test project, then
Closing and re-opening Visual Studio 2008
I'm not sure which of these steps were explicitly necessary, but this "kitchen sink" approach resolved the issue for me.
Update: This Microsoft article states that when a solution is compiled, assemblies found in the GAC are never copied to the output bin\ folder, even if "Copy Local" is set to true.

In my case I had two the same (almost) assemblies with different locations.
The tested project was referenced to the first assembly and the UnitTest project was referenced to the second one (they were absolutely the same).
So check carefully all of the project references.

Related

`FileNotFoundException` when running test(s) in VS2013

I upgraded to Visual Studio 2013 after using VS 2012.
In VS 2012, when created new Test Project and add files to be "Copy Always" the visual studio copied them into bin/debug and while running the current directory(Environment.CurrentDirectory) was "bin/debug".
In VS 2013 the current directory is "TestResults/something+guid" and VS 2013 is not copying the files to this folder so an "file not found" exception thrown.
How do I change back the current directory to bin/debug in VS2013 to be like VS 2012?
Thanks!
The proper way to handle this scenario is to use DeploymentItemAttribute or test settings config to include the file(s) you want. It is this way because not all tests require the same files, different tests may require different configs entirely, or you may have several test runs and would need to inspect test artifacts to understand why one run failed and another succeeded (where the only difference was a referenced assembly, or a loose file.) Further, when run in a hosted environment (Team Foundation Server, for example) this same pattern is used on the agent server(s), writing a test to set current directory would fail when run on something like a TFS test agent.
As an aside, the path you see during a test is not actually VS2013, it's the MS Test Agent itself (a second process runs tests for sandboxing purposes, I beleive it has been this was since VS2010.)
It sounds like you have an additional problem, all but guaranteed to be one of the following. Without seeing the exception detail I'm making a best guess, these are in order of likelihood:
You have a loose file such as "test.txt" included in your test project and you have a DeploymentItemAttribute decorating your test method. But the "Copy to output folder" setting for "test.txt" is set to "Do not copy".
Changing this setting, rebuilding, then retesting should work.
You have a missing assembly reference, likely for a non-BCL assembly (or, more specifically, you're missing a reference to an assembly which is referenced by an assembly you are referencing.)
To fix this problem you should load fuslogvw.exe and use the log data to discover any missing assembly reference(s) to your test project.
You have referenced a native DLL or assembly which is compiled for a specific processor architecture (x86 vs x64 vs MSIL) and it cannot be loaded within the processor architecture which MS Test Agent is running.
The solution to this is to use an assembly with the correct processor architecture when running the test.
Between project references, "Copy to output directory" setting, and [DeploymentItem], your tests should be finding the file(s) they rely on.
Let me know if you need more info, if you're still having a problem i would suggest editing the question to include the exception detail (or at least the parts that matter, such as Type, Message and the first 5 lines of StackTrace.)

Missing Method exception "System.Web.Routing.RouteValueDictionary System.Web.WebPages.TypeHelper.ObjectToDictionaryUncached(System.Object)

I've created a new project in Visual Studio 2013.2 with WebAPI and MVC enabled. Right out of the box, compiling the generated project and running gives me the exception. Looking around here, I've come across the following two questions:
Mvc 5.1 MissingMethodException System.Web.WebPages.TypeHelper.ObjectToDictionaryUncached
System.Web.WebPages.TypeHelper.ObjectToDictionaryUncached
Both these answers involve assembly redirects; however, in my case the assembly redirects are present and I'm still getting an issue. My problem is that the GAC is loading version 3.00.11001.0 which is listed under assembly version 3.0.0.0 and my application wants 3.20.20520.0 which is also listed as assembly version 3.0.0.0. (Note that in diagnosing the project I installed the 5.2 pre-release nuget package, but I had the same problem with the original versions, I just don't have those readily available)
Since the GAC is preferred over the bin directory, it seems that my development machine will always pull the wrong file.
Is it safe to remove these files from the GAC? It appears that these are required for Visual Studio to produce Razor intellisense
Removing the Assemblies from the GAC did behave exactly as expected. The Razor intellisense for the project stopped working; however, the application began functioning properly.
You have to add the reference of System.Web to get it working.

Visual Studio 2010 - Debugging / Build Problems

I am using Visual Studio Professional 2010 and the Team Foundation Server Express (beta). My VS Project (C#.Net / WPF) has been migrated from VS 2008 (without TFS) to VS 2010 (with TFS).
Whenever I apply changes to my code and try to debug my application, I get messages like This breakpoint will not be hit. (in german: Der Haltepunkt wird momentan nicht erreicht. Der Quellcode weist Unterschiede zur Originalversion auf.) and the project is started using the old executable version (the one with the last successful build). No errors occure, the code is OK, but the changes are not applied either.
When I manually cleanup and rebuild my project, everything works quite fine - but there has to be a fix for this issue?
Edit: I just added a new project to my VS solution and checked it in on the TFS Server. Using this new project the problem does not occure. Even when I add the same dependencies I used in the project mentioned above, the debugging and building of the new project works fine without the errors mentioned above.
Maybe this information helps you to lead me to a solution.
It's not clear whether existing answers are not sufficient. I can't know exactly what's causing your problem; but, I can detail some places this potentially comes up.
The first area that I commonly see this is when a project references an assembly directly. You can create a project that creates an assembly. Another project might use that assembly and you can reference by assembly directly (and not add a reference to the "project"). This disconnects VS from really knowing it needs to "build" that referenced assembly first and it will sometimes get out of sync with the debugging symbols (PDB). You can tell if a project has been referenced or an assembly has been referenced in the properties of the reference (expand References in Solution Explorer, right-click a reference, and select Properties). A referenced project will not have a Specific Version property, while an assembly reference will. You can sometimes also tell from Project\Project Dependencies. If you have a reference to an assembly generated by another project but that project isn't a dependency in Project Dependencies, it might be an assembly reference. To fix this, you can usually just delete the reference and add a reference to the project.
I've also find that sometimes breakpoints confuses the debugger. If I have many breakpoints or they've been kicking around a long time, the debugger sometimes does some weird things. If I delete all the existing break points (Debug/Delete all breakpoints) and re-apply them the debugger is usually much happier.
You can find the answer here. The assemblies might be in GAC or a project or some projects need to be rebuild to generate the pdb files again, which are used for debugging. If you don't choose to rebuild it might use the old pdb files.
My guess is that you are putting breaking points somewhere your program can't access them.
Ex:
const int x = 5;
if(this.x == 1)
//do sth <--- breakpoint here
If you are running a mixed mode application (unmanaged native C++ & managed C#), make sure to set Enable unmanaged code debugging in your C# application's Properties window.
You have to rebuild, there isn't an easier way around it.
The program database files (PDB) need to be recreated. You should also have your configuration setting set to debug.
Also the first answer to this question must be of help as well.
This happened to me when I started VS as an admin, and it also happened to me when the project is set to a different architecture than a DLL that I used in this project.

Unable to compile .NET application with referenced TLB when library is not registered

I have a C# 4.0 application that is referencing a type library from a C++ application. This is used for some secure COM interop, a question I originally had asked here.
On my development machine this second application is installed so I can compile without any issues. If I attempt to compile on our automated build server, or any machine with Visual Studio installed but without this second program, I receive the following errors and compilation fails:
Text for google:
The type or namespace name could not be found (are you missing a using directive or an assembly reference?)
Cannot get the file path for type library "guid...." version 1.0. Library not registered. (Exception from HRESULT: 0x8002801D (TYPE_E_LIBNOTREGISTERED))
The referenced component 'SecurityAgentLib' could not be found
Picture for readability:
I'm not sure how to get around this other than by installing the application that registers the actual dll that implements these types, but I don't want to do that on our build server. The code that uses these types are wrapped in a class that is never instantiated unless prerequisite checks are run to verify the app is actually installed, so there is no chance of a runtime error. In fact I can run my app just fine on a machine without the second app installed - I just can't compile it there.
In visual studio the reference points to the .tlb file which is included in the solution directory, so the tlb file itself is present.
I can't imagine it should work this way, and I've searched around, but I'm apparently not searching for the right terms.
EDIT:
Running tlbimp.exe generates a dll but the type library should be sufficient for compilation, I thought at least. There is also an issue of broken references. I was reading this article Troubleshooting Broken References and it says that if the reference was to a COM component that is not installed than installing the component corrects the error, which is true.
Installing it on the build server really isn't an option. Opening visual studio and re-adding a reference if the path was broken doesn't work either.
I was able to use tlbimp to create a dll and used visual studio add a reference to that dll. That let me compile, but how would this work in an unattended build server?
EDIT
Okay I came up with two solutions that worked given my requirement of this all being unattended
Ran tlbimp to create a dll from the type library. I removed the reference to the tlb from my project and added a reference to the dll itself. When the source code was copied over to a new computer it compiled without issues.
In this scenario ideally we would checkout from SVN on the build server and copy the latest DLL from the second project, then compile this project.
I also removed the tlb and added the dll in visual studio and did a diff on the .csproj file. I don't see any downside to just having a reference to the dll instead of the tlb but if needed the build server could make modifications directly to this file to remove the tlb section and add a reference to the dll following a build of the second product.
Here are a couple options that each worked.
Ran tlbimp to create a dll from the type library. I removed the reference to the tlb from my project and added a reference to the dll itself. When the source code was copied over to a new computer it compiled without issues.
In this scenario ideally we would checkout from SVN on the build server and copy the latest DLL from the second project, then compile this project.
I also removed the tlb and added the dll and did a diff on the .csproj file. I don't see any downside to just having a reference to the dll instead of the tlb but the build server could make modifications directly to this file to remove the tlb

What do you do about references when unloading a project in Visual Studio?

When you unload a project in Visual Studio, any referencing projects get warning triangles on their reference to the unloaded project. I've written myself a macro to do clever stuff (detect add/remove of project and transform any references from-to file/project dependency), but I can't believe that I'm not missing something much simpler. How can the unload function be any use if I have to go around manually changing references (and it breaks the 'personal solutions/shared projects' team development paradigm).
(This question is related to answers to this question about structuring large solutions in Visual Studio - some answers mentioned having solutions with lots of projects, but 'unloading' unused projects to improve performance.)
For my projects, I create an assemblies folder which the projects automatically copy into from a set location to which other projects copy builds.
Post-build for referenced assembly's project:
if not exist "C:\builds\Project1" md "C:\builds\Project1\"
copy "$(TargetDir)$(TargetName).*" "C:\builds\Project1\"
Pre-build for referencing projects:
if exist "c:\builds\Project1\" copy "c:\builds\Project1*.*" "$(ProjectDir)assemblies"
The project file points to its assemblies subfolder for references so even if the source projects are unloaded from the solution, the last-built assemblies will be used without the performance problems of having the whole project in memory while developing.
What are the advantages of having projects in the same solution if you use file references?
If your app.exe uses utils.dll and you change the code for utils.dll, then if it's in the same solution VS will notice the dependency and recompile both. If it's not in the solution you'll have to jump out, recompile utils.dll seperately, then jump back in and recompile app.exe.
This becomes either more or less important depending on how many other dll's your exe is referencing, and how often they change (in team environments shared dll's change often in my experience).
There is also the side effect that if you have 100 projects in VS it will take a long time to process them all just to figure out if they need recompiling or not.
Unloading projects is meant to be a temporary action so you can edit the actual project file as XML (text). If you want to completely remove a project from your solution, you should use the "Remove" menu option, which will take care of removing any references to that project.
One advantage to using project references is that it allows you to easily debug through the code. It also automatically ensures that you are using the correct configuration build (ie, if you are building in "Debug" mode it will use the Debug version of the assembly). That being said, you loose some determinisim about which version/build of the dependent project you will pick up - project references mean you always use the latest.
Yes, for Visual Studio to determine build dependencies it must be able to see and build all of the projects which would mean project references.
I've just had a eureka moment reading through MSDN doc on structuring solutions and projects.
What I hadn't noticed is that in a multi-project solution, the context menu in the Solution Explorer proposes a Project Dependencies popup. Here you can define the project dependencies manually, if you haven't defined them by project references between projects.
See here (MSDN link, so will self destruct after a few weeks)

Resources