Reference resolution changes in Code Analysis and FxCop – Part 1
Another thing that we changed in Visual Studio 2008 Code Analysis and FxCop 1.36, was the way we resolved and located references.
These changes came down to two distinct behavior changes:
Strong names of references must now match.
Assemblies must now completely match the exact strong name (name, version, culture and public key token) to be considered a match for a reference. Previous versions of Code Analysis/FxCop allowed any assembly with the same simple name to be considered a match for a reference. This could cause it to pick the wrong reference when multiple assemblies with the same name were on the search path, which lead typically to bad consequences when it failed to find members that didn’t exist in the assembly it picked.
Most users should not see any functional change in 1.36 as analysis will just work as normal. However, for those that now have FxCop complaining that it can’t find a reference even though it seems to be present – simply make sure you point FxCop to the same references that you compiled against. Visual Studio users should not need to do anything – the correct references will automatically be used.
Direct references are now required.
Direct references of the assembly being analyzed must now be present, while indirect (references of references) remain optional. Analysis of a target assembly will not begin without the same binaries that it was compiled against being present*, whereas previous versions of Code Analysis/FxCop, would error, but would attempt to continue analysis.
This was a controversial decision, but makes sense when you understand the underlying technical reasons for this change; the metadata in an assembly simply does not provide enough information to provide meaningful analysis for some rules.
For example, assemblies do not contain:
- Information about base classes that live in another assembly. ImplementIDisposableCorrectly, IdentifiersShouldHaveCorrectSuffix and MarkAttributesWithAttributeUsage are examples of rules that need to know the base class of a type to be able to give significant analysis.
- Information about alternative overloads that may exist for a called particular method if that method lives in another assembly. For example, SpecifyCultureInfo needs to know if there is an alternate overload for a method that takes a CultureInfo – this requires looking in direct reference.
- Information about security attributes applied to members and types, if those member and types live in another assembly. The Code Access Security (CAS) rules such as DoNotIndirectlyExposeMethodsWithLinkDemands and MethodSecurityShouldBeASupersetOfType use this information for their analysis.
There a few other reasons not listed above, but basically the decision comes down to FxCop's analysis would be incomplete and incorrect if direct references were not required.
* Unfortunately, there are a couple of very small isolated scenarios where this is not true and FxCop could prompt for references you were never actually compiled against. I’ll talk about these scenarios and workarounds in Part 2.