views:

606

answers:

4

The full error is as follows:

The type 'System.Windows.Forms.Control' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.

and it points at the very first statement (an Debug.Assert line) in the very first class in a library project that doesn't need System.Windows.Forms (or so I thought). I know how to solve it: add the mentioned reference. But how do I find out what library is causing this error, or better, what part of the code triggers using the WinForms library?

Normally, you can add libraries that reference others, but you only need to add references to these others when they're actually used.


EDIT: Alternative solution

This or similar problems can also be resolved using the Binding Log Viewer Fuslogvw.exe from Microsoft's Framework Tools. It shows all attempts and successes of assemblies your application binds to.

+1  A: 

Use something like NDepend or Reflector or the Object Browser to check the dependencies of the assemblies you depend on.

I cannot think of any other way given the info above.

dice
That's the way I'd currently thought of as well, but it's either too rough (NDepent) or too granular (Reflector). I can also rollback my code changes until the moment the error rose, this will show the line that causes this. I hoped for something else.
Abel
A: 

Use .net Reflector to inspect you assembly and the ones called by it. Eventually you'll find out who needs System.Windows.Forms

sebastian
See answer by dice and my comment there, he said the same earlier.
Abel
+4  A: 

I suspect there's no line of your code that's causing this, since you say you aren't making use of the System.Windows.Forms types and the compiler error isn't pointing to a (useful) line of your code.

What I think is happening is that you're referencing a library which has a publicly-visible method or property that either returns a System.Windows.Forms.Control or takes one as a parameter. It doesn't matter whether you actually end up calling that method/property, the fact that it's publically visible means that your own code has to be able to resolve all the types that the library is using. If the library only used System.Windows.Forms internally, you wouldn't be experiencing this.

It also means just looking at the dependencies of the assemblies you're depending on may merely narrow down the list of suspects, since there could be some assemblies that depend on System.Windows.Forms internally (no problem) and the one troublemaking assembly that has a public parameter / return value of a type from the S.W.Forms assembly.

My suggestion is you just set up an empty project without a reference to S.W.Forms, then add each of your dependencies in turn and try to compile after each one.

Chris
This proves correct: There was a referenced lib that had a generic method that was restrained to `Control`, but wasn't used in any way. I knew about the possible causes, I just hoped for a "straight" way for finding the culprit. I used simple deduction this time (rollbacks until the problem arises)
Abel
I'm not sure there's an easy way of identifying the culprit, other than your suggestion (rollbacks) or mine (set up a testcase project and add dependencies one at a time until it fails to compile). The manifest of a .NET assembly contains details of all the other assemblies it depends on, but there's nothing that says "if you reference this assembly, you'll also need to reference that one too". Any tool that solved this problem would have to use reflection to check the types of all return values and parameters for every method in the assembly you're looking at - it's quite a specific task.
Chris
A: 

Okay, is there a magic trick to getting this stuff to work? I have a fairly simple file-based web app consisting of one aspx page and several classes in separate .cs files. Everything is on my own HD. The app itself builds without error and runs fine. Out of curiosity I decided to try out this nifty, easy-to-use unit test feature. So I opened each class file and clicked Create Unit Tests. VS generated a test project containing a set of test classes and some other files. Easy! But when I try to build or run the test project it throws a series of build errors, one for every class:

The type or namespace name 'class-name' could not be found (are you missing a using directive or an assembly reference?).

Am I missing something? I dunno, I just followed the directions. VS generated the unit tests, yet it claims to know nothing about the classes it generated them from. I like the easy-to-use part but I'm not too crazy about the doesn't-actually-work part.

DougLeary
You should really post your own question however, have you referenced your main project from the test project?
Josh Smeaton
Please read through the guidelines of StackOverflow (takes you about 1 min). In general: don't post questions as an answer. Post questions as, well, questions. Otherwise your chances of getting an answer are very slim.
Abel