We have a lot of assemblies that contain internal classes which we are unit-testing by using InternalsVisibleTo to make the internal classes visible to the Unit Test assembly.
This works fine, but the problem is that as soon as you use InternalsVisibleTo, it prevents the Code Analysis CA1812 warning (Avoid uninstantiated internal classes).
It also prevents CA1811: "Avoid uncalled private code".
I've done some investigation, and I've found quite a lot of unused internal classes that we weren't being warned about because of this.
My solution for the moment is to hand-edit the "AssemblyInfo.cs" file in each assembly to temporarily comment-out the InternalsVisibleTo so that I can compile just that project and discover unused internal classes.
This is a huge hassle, and of course if something like that doesn't get done automatically, it frequently doesn't get done at all.
A solution would be to be able to tell Code Analysis to ignore the InternalsVisibleTo attribute.
Does anyone know if such a possibility exists?
Try this:
#ifdef CODE_ANALYSIS
#else
[InternalsVisibleTo(...)]
#endif
Related
Before deploying my project, I would like to set all public methods to internal methods. Does someone know a built-in function in Visual Studio or an external tool to do such tasks?
With some trivial refactoring, ILMerge can work here. ILMerge can merge multiple assemblies into one, and change the accessibility of everything that is not part of the primary assembly to internal. By separating your current project into two projects (a library containing all the code, and a helper executable that does nothing but forward to the real code in the library), you can, after a build, merge them back into a single file, in which all the library bits are no longer public.
If you have properties/methods public for test reasons you should have a look at Brad Wilsons blog: Testable Object Pattern
This way you don't have to switch, everything stays internal in development.
Or have a look at Jon Skeets suggestion on InternalsVisibleTo
I can only think of two reasons you would want to do this:
Security. In this case you have the wrong idea: access modifiers are not a security mechanism. They are a design concern, describing how an API presents itself. Any debugger will still give access to all your methods, regardless of their access modifiers.
You have another assembly that you use during development that should have full access. In this case you can leave everything internal and make it a friend assembly.
I applied InternalsVisibleTo to one of my projects in order for its internals to be visible for test projects. However, (this is weird I know) I need to mark a few internal classes so that they won't be visible to the projects which is indicated through InternalsVisibleTo.
Is there any attribute I can apply for this that the compiler is aware of?
Anderson Silva is correct. There is no way to do this. You should consider moving the types to a new assembly. Alternatively, you could think about applying the [EditorBrowsable(EditorBrowsableState.Never)] attribute to hide the types from IntelliSense, although if the user knows about them, the code will compile.
I'm writing a library that has a bunch of classes in it which are intended to be used by multiple frontends (some frontends share the same classes). For each frontend, I am keeping a hand edited list of which classes (of a particular namespace) it uses. If the frontend tries to use a class that is not in this list, there will be runtime errors. My goal is to move these errors to compile time.
If any of you are curious, these are 'mapped' nhibernate classes. I'm trying to restrict which frontend can use what so that there is less spin up time, and just for my own sanity. There's going to be hundreds of these things eventually, and it will be really nice if there's a list somewhere that tells me which frontends use what that I'm forced to maintain. I can't seem to get away with making subclasses to be used by each frontend and I can't use any wrapper classes... just take that as a given please!
Ideally, I want visual studio to underline red the offending classes if someone dares to try and use them, with a nice custom error in the errors window. I also want them GONE from the intellisense windows. Is it possible to customize a project to do these things?
I'm also open to using a pre-build program to analyze the code for these sorts of things, although this would not be as nice. Does anyone know of tools that do this?
Thanks
Isaac
Let's say that you have a set of classes F. You want these classes to be visible only to a certain assembly A. Then you segregate these classes in F into a separate assembly and mark them as internal and set the InternalsVisibleTo on that assembly to true for this certain assembly A.
If you try to use these classes from any assembly A' that is not marked as InternalsVisibleTo from the assembly containing F, then you will get a compile-time error if you try to use any class from F in A'.
I also want them GONE from the intellisense windows. Is it possible to customize a project to do these things?
That happens with the solution I presented above as well. They are internal to the assembly containing F and not visible from any assembly A' not marked as InternalsVisibleTo in the assembly containing F.
However, I generally find that InternalsVisibleTo is a code smell (not always, just often).
You should club your classes into separate dlls / projects and only provide access to those dlls to front end projects that are 'appropriate' for it. This should be simple if your front-end and the group of classes it may use are logically related.
If not then I would say some thing smells fishy - probably your class design / approach needs a revisit.
I think you'll want to take a look at the ObsoleteAttribute: http://msdn.microsoft.com/en-us/library/system.obsoleteattribute%28v=VS.100%29.aspx
I believe you can set IsError to true and it will issue an error on build time.
(not positive though)
As for the intellisense you can use EditorBrowseableAttribute: http://msdn.microsoft.com/en-us/library/system.componentmodel.editorbrowsableattribute.aspx Or at least that is what seems to get decorated when I add a service reference and cannot see the members.
Can I restrict classes from a specific namespace from referencing classes in another specific namespace? Both namespaces exist in the same .NET assembly.
Example:
namespace LegacyCode
{
class LegacyClass { ... }
}
namespace NewCode
{
class NewClass {...}
}
I do not want classes from 'NewCode' to be able to reference classes in 'LegacyCode'.
Options:
Have different assemblies (makes deployment harder, build takes longer)
Using a tool like NDetect (costs money!)
Does anyone have any other ideas?
Consider marking the classes with the Obsolete attribute. This will cause any code that isn't itself marked as 'Obsolete' to generate a warning during compilation.
Enable 'Treat warnings as errors' setting on the 'Build' tab of the project file to cause this warning to fail compilation with an error instead.
Edit:
Agree that seperate assemblies is a good strategy to facilitate fading out this code. This won't stop people referring to it though. The obsolete attribute makes it clear that this code is, um, obsolete.
Edit #2:
Thanks to Dan Tao for pointing out the overloaded constructor of the Obsolete attribute. This means you can enforce whether usage of a something should be treated as an error or not, without having to enable treat warnings as errors. There is also usefully the option to specify a message instructing the user of a workaround. This message is displayed during compilation in the error/warning.
Document the design, talk to people, review code. Don't try to throw technology at people problems. (The review part can become more effective with tools like NDetect, though.)
If you really need the isolation of design changes, go for separate assemblies: that's the intended design mechanism. But be sure you have a reasonable versioning scheme both for the interface and the implementation.
I think separate assemblies are the only possible solution.
MS uses the System.ObsoleteAttribute attribute to mark obsolete/legacy code. This attribute provides an ctor that creates a compiler error. Though, I'd use this if there are not too many legacy classes.
As others have said, use the obsolete attribute (Even if you have to rename it).
But go one step further. DELETE ANY Legacy method that is NO longer used as soon as possible. This will prevent someone from using it later. You should start to see the Compiler warnings due to the obsolete attributes to drop over time.
You might even make it a daily one hour long test to eliminate as many compiler warnings as you can... Maybe you pitch in to buy the daily winner a beer (or soft drink..;) after work.
Having recently learned of the DebuggerDisplay attribute, I've found it quite useful. However, one thing that surprises me is that it doesn't have a [ConditionalAttribute("DEBUG")] attribute attached to it. Is there some way to force this or is it a bad idea to try? Or does it not matter for some other reason?
The [ConditionalAttribute("DEBUG")] is only used for optimising out method calls.
If you really want to remove these from your builds you can use #ifdef so that the code is only compiled in release mode.
One thing to bear in mind is that you can still debug binaries in release mode, as long as you have the pdb files it shouldn't matter. Release mode just clears up variables sooner and applies some compiler optimisations
As I often have to debug things in Release configuration builds that don't have the DEBUG directive, I would not want these hints to the debugger to be removed.
However, if you have some proprietary or confidential information in the way you display things when debugging that you don't want to make it into your release build, you may want to consider using the ConditionalAttribute or #if/#elif/#endif preprocessor directives to control what is emitted into your release builds.
For example, you could do:
#if DEBUG
[DebuggerDisplay...]
#endif
public class MyAwesomeClass
{
}
This would ensure the attribute is only emitted when the DEBUG directive is given.
I'll share a pattern that I've come to appreciate using partial.
public partial class MyClass{
//class details here
}
And then elsewhere:
#if DEBUG
[DebuggerDisplay("DebuggerValue")]
public partial class MyClass{
//anything needed for debugging purporses
}
#endif
This gives the ability to use DebuggerDisplay or other attributes without cluttering-up the base class.
I've been using a handful of files, all wrapped in #if DEBUG to hold these Debug-Partials. It helps keep the core classes cleaner and I don't have to remember to start/end compiler directives for each attribute.
I would think it would be a bad idea, because a lot of times the thing you're attaching the attribute to has some other use besides just showing it in the debugger, IMO.