The right way to use Globals Constants - c#

In almost every project, I can't decide on how to deal with certain global constant values. In the older days, when I wrote C++ programs which didn't used dll's, it was easy. Just create and .h file with a number of const that described certain constant values for my project. Then I had every file include it, and ta-da! It worked. Clean, respected the DRY principle and was simple.
Now my projects are C# .Net, which gives me a large range of options to deal with this problem. From what I know:
Create an Assembly whose only purpose is to hold constant values for my project. Every other Assembly should then reference this one. I respect DRY and KISS, since adding references is simple enough. Main problem here is that I'd need to recompile the whole source to update those values.
Use a app.config file and have all other Assemblies retrieve the constant during initialization. So I add the overhead of having to initialize everything just to access a global value. Is more flexible but also more painful.
Use resources. I think it's the same as with app.config.
So, I know there's a better way to do this constants declaration. But I don't know and, so far, have been unable to find how to do it. Can you please help? I have candy!
Thanks all

Er, assuming that your constants aren't enormous, you should just be able to declare them as public const in a class of your choice:
namespace MyProject
{
public class Awesome
{
public const int SomewhatAwesome = 1;
public const int ExtraAwesome = 2;
/* etc */
}
}
You should include your const members in the classes that they relate to, i.e. if SomewhatAwesome and ExtraAwesome are used for and by the Awesome class, then they should be constants declared in that class. Don't create an extra assembly just to hold constant values, and don't create a dedicated static class or namespace for your constants unless there really is nothing else that groups the constants together.
The app.config file is for settings that can be changed by the end user at runtime. Don't put constants that shouldn't change in that file. Resources are for "big" objects, such as text files and images, that would be tedious or impossible to include as literal class members. Don't put simple things like integers and short strings in resources.

You could use the readonly keyword instead of const to avoid having to recompile everything when the values change.
Excerpt from MSDN:
While a const field is a compile-time
constant, the readonly field can be
used for runtime constants
See this link for more details.

For C# projects, if you want constants, arguably the best thing to do is use the Settings file provided in Visual Studio under your project settings. It supports custom types, and AFAIK anything that is marked as serializable.
As many developers have told me, don't reinvent the wheel. There are two setting types, user-settings and application-settings, the main difference being that application-settings are read-only at run-time. That's essentially what you want, it sounds like.

Looks like using a class is Microsoft's recommendation. http://msdn.microsoft.com/en-us/library/bb397677.aspx

If you want the values to be capable of being changed at runtime, use app.config.
If you want them to be fixed at runtime then you're going to have to (and want to, to stop users messing around with them) recompile every time you want to change them, so use whatever's appropriate for your language. In the case of C#, some kind of GlobalValues class/assembly.
Don't use a resource file for global values or settings unless you want to swap sets of values in and out as a group (e.g. when compiling for a different language).

I think the main disconnect here is trying to force a C way of thinking into a C# project. If you have a bunch of constants that you just want to throw in a file together, I would take that as a sign that you need to re-think your design. Spend some time to think about which class the each constant really should belong to and put it there.
That being said, I really don't think you should treat these constants differently from other data, they should live in a dll. This also has the added benefit of being able to version the dll should the 'constants' change.

I have a few projects that I've been working on at work and we decided to create a static class for our global values and functions:
namespace MyNamespace
{
public static class MyGlobalClass
{
//Global stuff here
}
}
That way all global items are always visible and you don't have to instantiate the class to use them.

compile time constants vary with the universe in which you inhabit. So pi and e are compile time constants.
runtime constants could potentially vary with each new version.
settings could potentially vary each new time an application is run (or more often depending on how settings are implemented, i.e. db drive, config file driven, etc).

Try to avoid the God class and static 'helper' classes if you can help it. You should try your best to move the constant data into the appropriate classes.
I'm assuming that since you are using C# you want to develop with proper object oriented designs, principles, and patterns. Remember, objects are about behavior --not necessarily functionality. In my opinion, thinking functionally leads to producing procedural code.
You can use the Singleton pattern when the data is used throughout many objects. Although, it's not necessarily a best practice. Lately, I've started using IoC dependency injection more in these situations with Unity and MEF.

Related

C# What are the Advised Coding Practises to place Constant String Literals in Class

Where is the best place to put string literals within the class? Should they be declared as constant members, should they be referenced in the method (provided the string literal is only ever used once), should they be put in a helper class or elsewhere?
Are you referring to strings that are displayed to user and require internationalization?
In .NET and Java you can use Resource Files that lets you use a key/value resource file. This has the added advantage of not needing compilation every time you need to change text, and you don't need to be a coder to be able to modify the resource files.
If you're just talking about internal strings that are used (like keys, IDs etc.) then I wouldn't fuss too much about it - some people like "constants.cs", while other like it within the file that is using them, and others like putting each set of constants in their own relevant packages. Just keep it ... Constant.

How to access common namespaces for XML parsing

I have stored my common namespaces used in my Linq to Xml parsing in a config file. Where is the best place to access them in my application? Put them in my base class? Create a Config Class that I can call (call namespaces via accessors), ? What would be deemed a good practice here. I currently have about 7 namespaces.
Thanks,
S
What is the requirement? You currently have the namespaces in a config file which allows you to change them without recompiling the application. If you feel this is useful, I would keep them in the file and, as you suggest, create a type to hold the values at runtime which can be passed as a dependency to any code which needs to know about the namespaces.
If however, you expect these namespaces to fixed for ever, it may be reasonable to hard code them into your base class or wherever else in the source code makes sense (this could also be done using embedded resources rather than string literals).
This latter option would have the benefit of reducing unnecessary noise in your config file and the need for the added dependency type, but I would suggest that, in most cases, it's probably just as well to use the config file pattern regardless. Yes it may be a little extra clutter, but in this business things that you think will never change have a habit of changing.
Also, you say that you currently have 7 namespaces. This suggests to me that you think you may have more or less in the future. For this reason, it sounds like you probably should be using the config file pattern.

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.

Is it possible to define an alias for a class in .NET?

The name of one of my classes was changed and I can't change it back. I have to mantain backwards compatibility and I don't want to write an wrapper with the old name.
Is there any easy way to give a class 2 names or to give it an alias?
Lifted from a comment by the OP:
Don't tell me to use the using directive since it must be done in the consumer side, and I don't want to change the projects that are using my library.
Arguably, your best option is to use a refactoring tool (like Resharper) to help you automate the conversion from the old name to the new name. However, if this is untenable to you for some reason, here are some alternatives:
If the types are in different assemblies you may be able to use a Type Forwarder. These allow you to redirect all references for a given type to an assembly ... but if IIRC, they can also redirect them to a new name as well.
Otherwise, within a single .cs source file you can apply a using statement:
using OldClassName = SomeNameSpace.NewClassName
This doesn't solve the problem globally, however, as it may become painful to change many .cs files to include this using statement.
Another alternative, may be to create a sub-class of the new type and name it the old name:
public class OldClassName : NewClassName
This gives you aliasing for the new class, but will require that you create duplicate public constructors and proxy static method calls to the renamed type. This is far from ideal ... and I generally don't recommend this.
Unfortunately, as the library author, the only way is X inherits Y, which has certain caveats.
It's possible but unlikely you could cheat with IL assembly.

C# code re-use via namespaces

I like to create a file full of custom functions which I have made, which I may use in another project or something. Now I don't fully understand how to go about this, normally in a language like php, you'd just create the php file and then go include("cust_lib.php") or whatever the file is called.
Now I think that the process involves the library having its own namespace, then either go using custom_lib; or custom_lib:: within the script (I don't want to get into a discussion over which is the best way to go here).
Is this right? Or should I create the library and convert it to a .dll, if so how do I go about this, what sort of syntax does a dll have inside it etc.
However if its just file within one project then I don't need to go down that route do I? I can just create the namespace and use that?
This is what I'm working for at the moment, and thought it would be something like this
namespace Custom_Lib{
~~functions to go here~~
}
However the functions have to exist within a class don't they? So that becomes something like
namespace Custom_Lib{
class custom_lib{
public string function1(string input){
return input;
}
}
}
So some help, pointers, examples would be appreciated so I can wrap my head around this
Thanks,
Psy.
(Yes I call them functions, that just comes from a long php/js etc background)
The normal approach would be to create a Class Library project, put your classes and methods in that project, making sure that those you want to expose are public. Then you add a reference to the resulting dll file in the client projects and you will have the functionality from the class library available to you.
Even if you decide to put it all into one single file, I would still recommend you to make it a class library since I imagine that will make it easier to maintain. For instance, consider the following scenarios:
You decide to put it in a file and include a copy of that file in all projects where you want to use it. Later you find a bug in the code. Now you will have a number of copies of the file in which to correct the bug.
You decide to put it in a file and include that same file in all projects. Now, if you want to change some behaviour in it, you will alter the behavior for all projects using it.
In those two cases, keeping it as a separate project will facilitate things for you:
You will have only one copy of the code to maintain
You can decide whether or not to update the dll used by a certain project when you make updates to the class library.
Regarding the syntax issues: yes all methods must exist within a class. However, if the class is merely a container of the methods, you can make it (and the methods static):
public static class CustomLib
{
public static string GetSomethingInteresting(int input)
{
// your code here...
}
}
That way you will not need to create an instance of CustomLib, but can just call the method:
string meaningOfLife = CustomLib.GetSomethingInteresting(42);
In addition to Fredrik Mörk's well-written and spot-on response, I'd add this:
Avoid creating a single class that is a kitchen-sink collection of functions/methods.
Instead, group related methods into smaller classes so that it's easier for you and consumers of your library to find the functionality they want. Also, if your library makes use of class-level variables, you can limit their scope.
Further, if you decide later on to add threading capabilities to your library, or if your library is used in a multi-threaded application, static methods will likely become a nightmare for you. This is a serious concern, and shouldn't be overlooked.
There no question here. You answered it yourself. Yes, you have to construct a class to include all helper methods. And yes, you can either compile it to a dll if you want to reuse in multiple projects it or just add the source file to the project.
Usually I declare the helper class and all functions as static to avoid initiating the class each time I use it.

Categories

Resources