Using constants or global variables in 3 tier console application - c#

I have a 3 tier application setup like so with a console presentation layer. In my business logic I have a class where I declare a number of different variables that are fixed i.e. the values won't change. The values of these variables are taken from app settings.
Now the problem I'm finding is that my class calls off to different methods where these variables are being passed around via the method signatures. Is this good practice? If not, would it not be better using constants instead? If so, where should the constants live so I can access them where ever I need them rather than passing variables around?
EDIT
Adding some code for you guys. So they're global variables I am referring to here.
OK so in my console app (presentation), I currently have something like this:
public class Program
{
public static void Main(string[] args)
{
MainClass myClass = new MainClass(appSetting1, appSetting2, appSetting3);
}
}
Then in MainClass I have:
public class MainClass
{
private string _appSetting1 = string.Empty;
private string _appSetting2 = string.Empty;
private string _appSetting3 = string.Empty;
public MainClass(string appSetting1, string appSetting2, string appSetting3)
{
_appSetting1 = appSetting1;
_appSetting2 = appSetting2;
_appSetting3 = appSetting3;
}
public void MyMethod()
{
Method2(_appSetting1, _appSetting2);
Method3(_appSetting2, _appSetting3);
Method4(_appSetting1, _appSetting3);
}
}
I hope you can see what I mean. I'm finding myself passing around global variables across multiple methods. I just thought there would be an easier way of doing this? Such as creating a constants class or something on the lines of that? I'm not 100% sure of the best approach to go for.
In my MainClass I could just declare my global variables like this:
private string _appSetting1 = ConfigurationManager.AppSettings["appsetting1"];
private string _appSetting2 = ConfigurationManager.AppSettings["appsetting2"];
private string _appSetting3 = ConfigurationManager.AppSettings["appsetting3"];
But do I really want to be doing that in my business logic?

Another possibility is to create a Settings class that loads them and exposes them as public readonly. This has worked well for me in the past:
public class Settings
{
public static readonly string AppSetting1;
public static readonly string AppSetting2;
public static readonly string AppSetting3;
static Settings()
{
AppSetting1 = ConfigurationManager.AppSettings["appsetting1"];
AppSetting2 = ConfigurationManager.AppSettings["appsetting2"];
AppSetting3 = ConfigurationManager.AppSettings["appsetting3"];
}
}
The static constructor is called automatically before the first access to any of the variables, so you don't have to call it explicitly. Your program can access the variables as Settings.AppSetting1, etc.

I am of the config-free mindset.
If these things presumably don't change, then have an assembly that projects can reference that return the values.
I shy away from configuration files. I realise they are needed in deployment circumstances, but given that your requirement, I'd recommend a common class library that everything else can use and reference.
If you do have to change something supposedly constant, you change it in one place.

if they are in the app.config and shouldn't change you should always reference them from there rather than passing them as parameters. This way your intention that they are static values is clear in the code.
EDIT
Jims answer makes sense in that case. Its really just a short hand so instead of writing ConfigurationManager.AppSettings["appsetting1"]; you use Settings.AppSetting1. either way you would be repeating yourself if you declare them at the top every class into class level variables. I like Jim's answer better than mine though as you can extend it. I keep all config in the db and then use a singleton which has a proc call in the private instance constructor to load config. Jims answer could implement this later without you needing to change your calling code. Generally config files are a pain.

Related

Dependency injection pattern how to initialize variables of static class at beginning

I've been using dependency injection for about 6 months now and sometimes there is a situation I don't know how to handle in an elegant way.
Say I want a class for storing all my app settings in. This class is only initialized at beginning.
Please let me know how idea 1 can be executed (as I think this is the classic way) and if idea 2 is a valid pattern or if there is a better alternative.
Idea 1:
make this class static as its variables are only initialized and after that everything stays read-only. The problem with this is that I do not know where to initialize variables of this class. To initialize one of the variables a password needs to be decrypted which requires the use of IEncryption interface.
I would like to initialize these static variables before the main program actually start (so preferably in Startup.cs). I can't do that because I can't get the implementation of IEncryption in the DI container class, or at least I don't know an elegant way to get it. How should this be done with a static class? should I make another "middleware" between Startup and actual program logic where I can initialize static variables?
If I'm not mistaken simple data only classes that are application wide are ok to be static object even when using DI pattern
Idea 2:
Now I don't know if this has a name or if it's ever used. It's just something I came up with and it seems like a good solution for me but there might be an alternative I don't know of that makes it useless.
What if I instead of making this class static I make it as a normal class and initialize all static variables inside class constructor.
So something like this:
public ClientData(IConfiguration configuration, IEncryption encryption)
{
var section = configuration.GetSection(nameof(ClientData));
EdgeUrl = section.GetValue<string>(nameof(EdgeUrl));
EdgeAuthUrl = section.GetValue<string>(nameof(EdgeAuthUrl));
Username = section.GetValue<string>(nameof(Username));
Password = encryption.Decrypt(section.GetValue<string>(nameof(Password)));
OrganizationKey = section.GetValue<string>(nameof(OrganizationKey));
}
public string EdgeUrl { get; }
public string EdgeAuthUrl { get; }
public string Username { get; }
public string Password { get; }
public string OrganizationKey { get; }
I then inject IEncryption through the constructor.
I would definitely recommend the second approach, except that you should keep the properties as regular properties, and no static fields or properties.
You should be able to register this in the DI container as a 'singleton'. This ensures only one instance is created. So it will be kind of static in the sense that there 'is only one', but only in the context of the DI container rather than for the whole process. This allows more flexibility, for example if you want to different parts of the application to use different configurations.
This will require the class to be injected into each place it is used. Luckily the DI container should make that trivial.

What is the equivalent of a C/C++ global variable?

I am new to C#. Come from the C/C++ environment. My application has a List<Model> which is required all over the place, by different classes. The problem is that a copy will not do because this statement:
dataGrid.ItemsSource = myModelList;
requires the original by address. I tried changing some arguments around and passing that particular variable as ref but as soon as it is assigned with an equal sign, I end up with a copy. Correct?
You could make it a singleton.
However a concrete List needed all over the place would make me have a serious think about my design.
At the very least you should consider writing a class to control access to the list (add, remove, clear etc), and making that "global", otherwise you are going to be in deep in the brown stuff, until it hits the fan.
Create a Public Class and have the content you wish to pass declared static within the class. Then just access it as NameOfClass.NameOfMethod()
public class NameOfClass
{
public static RETURNTYPE NameOfMethod()
{
// Your Code
}
}
You can create a public class for it with a public static List inside it. That one you then can access everywhere.
eg
public class FakeGlobal
{
public static List<Model> MyModelList = new List<Model>();
}
or even make it a property with getter/setter.

Best way to make data (that may change during run-time) accessible to the whole application?

what is the best way to have data accessible throughtout the wole application? In my concrete example I load the settings of my application from an XML file into an instance of a Settings-Object, and I don't want to make these some absolute constants because the user should be able to change these (and see the effects) without restarting the program.
Now, I need to use certain of the (properties of the) settings in methods of other classes, but in this way they are not accessible. So in what kind of an 'Object' should I store the settings? I don't think it is good it each method that needs a setting across my application has to look into the XML itself. Also, passing the settings instance into every other class I use seems too cumbersome.
Thanks in advance!
In C# I always use a static classes to provide this functionality. Static classes are covered in detail here, but briefly they contain only static members and are not instantiated -- essentially they are global functions and variables accessed via their class name (and namespace.)
Here is a simple example:
public static class Globals
{
public static string Name { get; set; }
public static int aNumber {get; set; }
public static List<string> onlineMembers = new List<string>();
static Globals()
{
Name = "starting name";
aNumber = 5;
}
}
Note, I'm also using a static initializer which is guaranteed to run at some point before any members or functions are used / called.
Elsewhere in your program you can simply say:
Console.WriteLine(Globals.Name);
Globals.onlineMembers.Add("Hogan");
To re-state in response to comment, static objects are only "created" once. Thus everywhere your application uses the object will be from the same location. They are by definition global. To use this object in multiple places simply reference the object name and the element you want to access.
Define some simple Configuration (say) class:
public static class Configuration
{
/*runtime properties */
public static void LoadConfiguration(..)
{
/*Load from file a configuration into the static properties of the class*/
}
public static bool SaveConfiguration(...)
{
/*Save static properties of the class into the configuration file*/
}
}
Do not forget naturally default configuration, in case when config file for some reason missed.
Hope this helps.
Sounds like a perfect use of the Settings project page. You setup defaults, they can be modified and saved between runs of your application.
You can have a static class with static properties to get and set

Using Static method and variables - Good vs Bad

I am developing C# and asp.net web application.
I have general class called utilities, I have lot of public and static variables in this public utilities class.
Since this number is gradually increasing, I want to know is it good practice to store utilities methods and variable as public static.
Example of my code
public class utilities
{
public static string utilVariable1 = "Myvalue";
public static string utilVariable2 = "Myvalue";
public static string utilVariable3 = "Myvalue";
:
public static string utilVariableN = "Myvalue";
public static string UtilMethod1()
{
//do something
}
public static string UtilMethod2()
{
//do something
}
public static string UtilMethodN()
{
//do something
}
}
There's nothing inherently wrong with static classes, although they should typically not have state (fields). Your use of public static fields indicates that this is not the case, so it seems like you are using abusing the static keyword slightly. If your class needs to have state, then it should be a normal, non-static class, and you should create instances of it. Otherwise, the only public fields visible on the class should be const (consider the Math class, with constants such as Math.PI - a good use of static methods and fields).
Another consideration is cohesion. Methods typically exist grouped in one class because they are closely related in one way or another. Again, the Math class is a good example; everything in there has to do with maths. At some point, you would want to split your global utility class into multiple smaller, more focussed ones. See Wikipedia for some examples on cohesion, it sounds like your usage falls under "Coincidental cohesion (worst)".
There's nothing wrong with this approach for methods, but variables should really be const if they're going to be static and public. If they are subject to change then you should look at a different structure for variables that are being manipulated by more than one component.
Personally, I'm a fan of the Singleton pattern.
static is not a bad thing per se. Methods that don't need to access any member variables or methods should always be declared static. That way the reader of the code sees immediately that a method won't change member variables or methods.
For variables the situation is different, you should avoid static variables unless you make them const. Public static variables are globally accessible and can easily raise issues if multiple threads access the same variable without proper synchronization.
It is hard to tell for your case if it's a good or a bad idea to use statics, because you didn't provide any context information.
Creating one class to do it all is not a good practice, and it's recommended to structure your project, and keep stuff that belongs to each other separated from the randomness.
A great example of this was a project I took over from a co-worker. There was 1 class, called Methods. It contained over 10K lines of methods.
I then categorized them into approx. 20 files, and the structure was restored.
Most of the methods from that project were validating user input, which can easily be moved into a static class Validation.
One awful thing I notice is the mutable public and static variables. This is bad for several reasons:
Incorrect behavior, because if some method changes this, while it isn't supposed to do that, it causes other methods to behave improperly, and it's really hard to track down/debug.
Concurrency, how are we going to ensure thread safety? Do we let it over to all methods that work with that? Say if it's a value type, what will we let them lock on? What if some method forgets to make it thread safe?
Expand-ability (I hope you understand what I mean with that), if you have for example a static class data that stores all these public static variables, that you shouldn't have. It can store that once, if for example you might change your application structure a bit, and say want to make it possible to load two projects in the same screen, then it's very difficult to make that possible, because you can't create two instances of a static class. There is only one class, and it'll remain like that.
For number 3 a cleaner solution would be to store either a list of instances of a data class, or to store a reference to the default and/or active data class.
Static member, and private static members (or protected) are a good practice, as long as you don't make huge classes, and the methods are related.
Public and static variables are okay if they're not really variable.
The two ways to do this is by marking them constant (const modifier) or readonly (readonly modifier).
Example:
public class UtilitiesClass
{
internal UtilitiesClass() { }
public void UtilityMethod1()
{
// Do something
}
}
// Method 1 (readonly):
public static readonly UtilitiesClass Utilities = new UtilitiesClass();
// Method 2 (property):
private static UtilitiesClass _utilities = new UtilitiesClass();
public static UtilitiesClass Utilities
{
get { return _utilities; }
private set { _utilities = value; }
}
The advantage of method 1 is that you don't have to worry about thread-safety at all, the value can't change.
Method 2 is not thread-safe (though it's not difficult to make it that), but it has the advantage of allowing the static class itself to change the reference to the utilities class.
No, it is not a good practice for large applications, especially not if your static variables are mutable, as they are then effectively global variables, a code smell which Object Oriented Programming was supposed to "solve".
At the very least start by grouping your methods into smaller classes with associated functionality - the Util name indicates nothing about the purpose of your methods and smells of an incoherent class in itself.
Second, you should always consider if a method is better implemented as a (non-static) method on the same object where the data that is passed as argument(s) to the method lives.
Finally, if your application is quite large and/or complex, you can consider solutions such as an Inversion of Control container, which can reduce the dependency on global state. However, ASP.Net webforms is notoriously hard to integrate into such an environment, as the framework is very tightly coupled in itself.

Lookup class use enum, struct, public const, something else?

I'm creating a lookup class so a constant value will be used throughout all the projects.
The thing is, there are several solutions to create such a thing. I could create a single class with enums, structs or constants in it or create a single class for every 'object'. I'm wondering what would be the best solution.
First I thought doing something like this:
public static class Defines
{
public enum PAGELAYOUT_NAMES
{
STANDARD = "Standard"
}
}
But personally I don't like using strings in enums that much.
Another option would be to use a struct, which is even more ugly if you see the code:
public static class Defines
{
public struct PAGELAYOUT_NAMES
{
public static string STANDAARD = "Standaard";
}
}
This looks a bit better, but could be confusing when having a lot of options:
public static class Defines
{
public const string PAGELAYOUT_NAMES_STANDARD = "Standard";
}
While typing this post, I think this will be the best/clean option:
public static class PageLayout
{
public const string STANDARD = "Standard";
}
Any other suggestions?
Filling up the project with several classes which only define some constants seem to me like a lot of overhead and clutter.
Edit
It wasn't very clear in the original context, but the lookup values aren't limited to only strings. Some very good suggestions below are only possible when you use only strings, but Int's, DateTime and other types need to be supported also. Got some nice ideas from the answers here, I'll try out which one will work best in my current project.
Final implemented solution
Thanks to the suggestions below, I've implemented the lookup classes like this:
internal class Base<T>
{
internal T Value{ get; private set;}
internal Base(T value)
{
Value = value;
}
}
public class PageLayout
{
public static string Standard { get { return new Base<string>("Standard").Value; } }
}
This is based on an answer given below.
Reason is because now I can use this for non-strings & integers also, which isn't really possible with an enum with a description and a resource file, even though that would feel cleaner to me.
Depending on what exactly it is you're doing, you probably want to look at Resources.
You define an xml file (or use the designer to help you), and it gets compiled into an assembly (either embedded, or a "satellite assembly").
Right-click the properties node under your class library in the solution explorer, click "Open" and go to the resources tab. It's pretty simple to get started from there.
Once it's set up, it's easy to get at the values from code e.g:-
String s = Resources.PageLayoutNames.Standard;
There are a few complications, but without knowing more about your app I can't advise more. The one that comes to mind is if you're unit testing ASP.NET applications you need to make sure that the resource gets embedded rather than deployed as a satellite otherwise the unit tests don't work.
They're also used for globalisation, so it's good to be familiar with them.
Edit:
Alternately after reading your question again, I'm inclined to ask "What do you need the string for at all?".
What are you doing that you can't do with just an enum?
enum PageLayouts
{
Standard,
ExtraAwesome
}
If you're trying to map text for display to an enum type, there are a bunch of ways to do that e.g. by using the DescriptionAttribute
enum PageLayouts
{
[Description("Standard")]
Standard,
[Description("Extra Awesome")]
ExtraAwesome
}
You can't give the DescriptionAttribute a resource key out of the box, though. You have to subclass it if you want to support globalisation...
I prefer this way using a factory style static properties. But it depends on the exact scenario. You can use string or enum as the field.
public class PageLayout
{
private readonly string LayoutType;
private PageLayout(string layoutType)
{
LayoutType = layoutType;
}
public static Standard {get {return new PageLayout("Standard");}}
}
Then in calling code use PageLayout.Standard
People advise against public nested classes, so in your earlier examples Defines should be a namespace rather than an outer class.
I always use the
public static class PageLayout
{
public const string STANDARD = "Standard";
}
approach.
I do however create more classes than one: When i use a lot of sessionvariables, i create a (public static)
class SessionNames
And i do make a difference between soultion wide constants and project wide constants.
sometimes the constants for one project (for example 20 placeholders in a PDF you have to create) have nothing to do with the other projects so i make that a project class, but when i have solution wide constants i create a class at the same place as i put my string extensions etc.

Categories