C-J Berg: Gendarme looks very interesting!
I especially liked this quote from the main page:
"The current Gendarme framework, Gendarme.Framework.dll, is a work in progress. It will probably change a lot before 1.0 is released. It's main goal is to make it easier to write and test rules."
"We also removed the Reflection 'bridge', that is, the ability to create CCI objects from their Reflection counterparts and vice versa."
This is the most annoying thing. Anyway, someone could have used the Cci library to generate code based on already parsed IL ( available in a high level form )... but of course it would have been improper.
Let us write our own IL parsers...
Go check out Mono.Cecil, it has a high level parser already.
Fx-Cop is great at what it does and it looks like you are currently taking advantage of something that it's not [currently] meant to do; that is, offering an API to automate custom rules. From what I can see, the FxCop team have realised that a lot of their types don't need to be exposed and are quite correctly 'concealing' them (either as internal or private). I for one would be glad of this decision if I were looking through their API 'contracts' -- I wouldn't want to spend time creating and trying to use exposed types that weren't mean to be exposed.
I do see the need to automate testing of custom rules, but I think this should be designed as an apporpriate [public] API.
Of course, this doesn't anwser the more general question "How do I design an API that hides irrelevant stuff but also enables the irrelevant stuff to be tested?"
In fact, in the paragraph above, I was going to use the term 'design an API that is both OOD compliant and easily tested', but, as Framework Design Guidelines quite correctly states, API's are not mean to be Object Oriented (the implementation is OO, not the public API).
So, I suppose the question really becomes 'How do I hide my OO implementation but make it easily testable?"
One way is to have the unit tests in with the implementation. I'd prefer not to do this, but I've done it in the past. I've also made the odd type here and there public instead of internal.
I've been toying with the idea of having a 'Unit Test Facade' object in my OO code/API. Anyone use the 'API' can see my intent from what's exposed, and anyone running unit tests can exercise the implementation via the facade. Of course, this adds overhead, but does make the distinction between the API and implementation.