Can I force a dependency between namespaces in C# - c#

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.

Related

How to get Resharper to show "private" on members and "internal" on classes as redundancy errors?

For class members the private modifier is redundant.
For classes the internal modifier is redundant.
Is it possible to get Resharper to show these as code errors?
In short: no.
We have only 'code cleanup' functionality able to remove redundant private/internal modifiers, but no code inspection like this. This easily can be done via plugin or issue request :)
There is no default out-of-the-box rule that enforces this. And I must say that I haven't seen a coding guideline in the last years that ever suggested not specifying the access level on anything. Usually specifying the access level is seen as a good thing, since it shows that there has been at least some thought into the desired level.
Of course some people set everything to public, but then again, that's something your rule won't see anyway.
You'll need to create a custom StyleCop rule (with the StyleCop plugin for Resharper) or a Resharper plugin to detect and flag these issues. It shouldn't be too hard, since the "error" is not too complex and the list acceptance criteria would be short and simple.

Reverse of Deprecated / Obsolete

I have a functionality in my code, but it will be available from next version. Is there any tags to notify that it is not in use, but will be available in future. I just have one way ie, [Obsolete] with custom message. Expecting other than this.Thanks in advance.
If it is not available in the current version, don't make it part of the public API. Don't expose stuff that shouldn't be used by consumers of your library.
And even when it's not a library, don't add code that you don't yet need. That violates the YAGNI principle. Add the code only when it is actually needed.
You can create throw a CustomError message from that method saying "This method is not available for the current version. It is for future" something like that.
Or else you can make the method as Obselete and specify the reason in the message.
[Obsolete("I have written this method for future use. Do not use it in the current version.")]
Judging from your question, I assume you want to generate a compiler warning when someone attempts to call this method, stating that it has not yet been implemented.
ObsoleteAttribute is hard coded into the C# compiler as something that should generate a warning message. Therefore there is no way to mark a method as 'to be implemented in the future' without modifying the compiler itself.
From the C# Spec:
The attribute Obsolete is used to mark types and members of types that
should no longer be used.
If a program uses a type or member that is decorated with the Obsolete attribute, the compiler issues a warning or an error.
Specifically, the compiler issues a warning if no error parameter is
provided, or if the error parameter is provided and has the value
false. The compiler issues an error if the error parameter is
specified and has the value true.
I suggest to not expose methods that are not yet implemented, since it makes no sense to use them. If this is part of a team development effort, specifying API contracts before developing specific modules, you should consider throwing a NotImplementedException or provide a dummy implementation.
Reviving this question as there is now a real solution thanks to Roslyn: Code analyzers.
Just add this Nuget package to your project and you'll be able to create attributes that will be picked up by the compiler!
The GitHub repo readme has the instructions, and it's really simple.

In C# (VS-2010), is there a way to fail a frontend build if a certain library class is used? (When normally it would compile just fine?)

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.

Prevent other developers using base methods within a class

I have a class that uses filesystem entities to manipulate data. We have several methods specifically designed to (attempt to) cope with some of the issues we face with this approach (file locking, non-existent files, etc.). Ideally I'd like to be able to issue a warning if another developer attempts access the filesystem directly via System.IO rather than using the helper methods.
Is this possible? The behaviour I'm looking for is to effectively mark methods such as File.ReadAllText() as if they were obsolete, but only within this project (NOT solution-wide).
I've done some digging around, and it looks like my only option is "tell them to make sure they use your methods". I'm hoping someone can give me a different, and more helpful answer. :)
--EDIT--
The suggestions of a custom StyleCop or FxCop rule are good, but unfortunately impractical in this scenario (not every developer in the department uses these excellent tools), and the legitimate methods that do the file access do use System.IO. Adding "ignore" attributes to the legit methods is a dangerous idea, too. If someone sees how I've "broken" my own rule, they'll likely copy the attribute to their own method.
Use a static analysis tool (such as StyleCop or FxCop) with a rule that captures "Do not use System.IO directly." Then integrate it as part of your automated build process and throw up if someone does try to use System.IO directly. No one likes to break the build.
You can write custom analysis rule for FxCop/Visual Studio Code Analysis and run these as part of your automated build.
Hmm. Not tried this myself, but how about forcing people to use your custom file handling classes, by using a namespace alias that "hides" the genuine System.IO. If I remember rightly these are applied at a project level.
Not sure if either of these suggestions are valid as I've never done them, but some food for thought:
Isn't this what "Enterprise Templates" are designed for? Don't they allow you to craft a policy file that restricts the allowed project references?
Alternatively, while not foolproof, could you add a pre-build event to the project that throws a warning if System.IO is referenced?
Can you add some custom functionality to a source-control commit hook? It won't find existing violations (if there are any) unless those files are changed but should detect new uses?
Any good?

Is there any way to stop a method being called at compile-time?

I have some classes, which have several methods which I don't really want to be there, but are there simply because the XML Serializer needs them. Is there anyway to generate compile-time errors/warnings if they get called from user-code?
I am aware that I can implement IXmlSerializable, and I am also aware that I can separate out the classes into purely data storage classes, however, I am not asking a question about how I should design such a system, I am simply asking if there is a way to generate compile-time errors/warnings if they are called by anything that is not the XML serializer...
You can add
[Obsolete]
to the method. The IsError property of ObsoleteAttribute controls whether an error or warning is generated, and you can provide an explanatory message too.
You could decorate the members in question with the ObsoleteAttribute. Its intention is a bit different, but it will generate compiler warnings (or errors) when called from user code.
You can hide the methods from users intellisense using the [EditorBrowsable] attribute, and from property designer using [Browsable], attribute.
I don't recommend using the [ObsoleteAttribute], because it conveys a different meaning to what method state actually is. Instead use a comment indicating that the method should not be used from user code.
Also keep in mind that there are lot's of users that compile their code with threat warnings as errors, which will make impossible for them to compile valid code, in this case.

Categories

Resources