Im creating an Windows Phone app and I find myself writing the same MessageBox.Show("Same error message") multiple times. For instance
"Could not connect to server"
This happens when the user do not have internet access.
Is there somewhere I can put it so that I write the text once and fetch the same text all over the place?
I could write a static class, but maybe there is a file for this?
Is there somewhere I can put it so that I write the text once and fetch the same text all over the place?
Yes, there is a special kind of file specifically for this, called strings.resx. It lets you write
MessageBox.Show(strings.ServerNotFound);
instead of
MessageBox.Show("Server not found");
The added benefit (in fact, the intended purpose) of using strings.resx is that your application becomes easily localizable (see answer to this question): adding proper translations and setting the current locale is all it would take to change all strings that your application displays to users with their proper local translations.
If you want it to be multi-lingual in the end I'd go for the Resource.resx file.
If not, you can go for all kinds of solutions:
keep the string there where they make most sense, in the class where you use them
store them all together in a dedicated class
Like:
class MyClass
{
private static string MyString = "blah";
// other meaningful stuff
}
Or:
public class MyStaticStrings
{
public static string MyString = "blah1";
public static string AnotherString = "blah2";
}
You can create a static variable in the App.xaml.cs page in the App class, so that you can access it all over the application.
Related
What I am trying to do:
I am working on a chat bot service where I have different channels of access. On one channel I want to use my Customer.resx file and on another channel I want to use my Worker.resx file.
The problem:
I know how localization works to switch between Worker.en-US.resx and Worker.es-MX.resx, but I am unsure how to switch from one normal resx file to a completely different context one. These will each be translated into other languages so I can't simply use Customer.en-US.resx and Worker.es-MX.resx as a workaround. I do know that I can build a custom culture using the CultureAndRegionInfoBuilder, but I would rather do this in a simpler way than that, something along the lines of how you do localization. I am currently building custom cultures using this method and I have Resources.worker-en-US.resx and similar for customer, but this is a round-about way and I know there must be a better way.
For clarification I know I can grab a resource file with ResXResourceSet, but the idea was that I would like to have two separate resource files with localization for each (worker.en-US and customer.en-US).
I would combine both of these as into one because resx's are really tied to cultures/languages. You can use a strategy pattern to get the right strings at the right time.
interface IStrings { string Foo { get; } }
class WorkerStrings : IStrings { ... }
class CustomerStrings : IStrings { ... }
As you know we don't have session in WinForm. I have several forms (Customer, Service, Operator, ...) in my project, and I take from Operator some values ( operator Name, Operator LastName and Profile Picture address). I want to store this values somewhere in run-time and whenever I need it, I can fetch it from where I stored it.
Is there an easy way to do this ?
I think these are the words of a long time web developer. I hear you my friend. I've been there...
Session object of web programming is just a workaround to work around the problem of saving state in a stateless environment. On the other hand winforms programming does not have this problem. Your application has objects that all keep their state information.
As for passing information from one form to another:
You can define parameters on the receiving forms constructor to pass
parameters. Then you define local variables in the receiving form to hold references to those objects.
You can set a separate method on the receiving form to
send parameters and call it from sender form.
You can make the information public on the sender
form (or some other place) and get it from receiving form when you
need it.
Which one is best? Depends entirely on your business case and application logic.
I believe that the simplest way to do this is to create a class that can be accessed from your forms which contains the data you want
Example
// Class1.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace myNameSpace
{
class Class1
{
public static string Name = "";
public static string LastName = "";
public static string ProfilePictureaddress = "";
}
}
Using this, whenever you would like to store or retrieve data, you may use myNameSpace.Class1. For example, if you would like to store into the Name, you may use myNameSpace.Class1.Name = "value";. This will set Name to value.
Thanks,
Happy Holidays! :)
also you can use project properties like this:
//write
Properties.Setting.Default["key"] = value;
Properties.Setting.Default.Save();
//read
value = Properties.Setting.Default["key"];
I want to declare a variable in such a way that I can access that particular variable and its value in all the asp pages in the project. Can anyone tell me how to declare a variable in C# such that it has project-wide scope?
You have a couple of choices and the best may require more specific information about what you are trying to accomplish. For example, do you need to be able to write to this variable as well?
But a simple approach is just to store it in the application object: Application["mydata"] = value;
Note that you can lose this data if your application is reset, which can happen from time to time. You can look at using cookies or a database to persist across resets.
Declare it as a "static" variable in a static class anywhere in the projects. You can declare it either as "internal" or "public".
However, you should always be careful about such a thing. If you need this, your design might need some work.
You can use a public property in the global.asax. That way you will be able to retrieve it from anywhere in the project.
global.asax:
private string _myvar = "";
public static string MyVar{ get { return _myvar; } set { _myvar = value; } }
any page code-behind:
string text = MyClassName.Global.MyVar
Based on what you said, I supose you want some kind of global variable.
If tha's the case you should learn about the Application object and, probably, initialize your variable in the Application_Start method of global.asax file
If you need some generic approach. Create a project in your solution called Common as class library. Add a class file and add some public static members there . Compile it to dll, and you are now ready to use the members within the solution and if you wnt to use the same in some other application you can use too by adding reference.
But if you need it for some specific time you can use either of them stated above. In addition you can also use Session["MyObject"] = object_value. All have cons and pros. Google and use what ever suits you best. You have various options now, :)
Application scope defined within your global.ascx file.
Thus: Application["VariableName"] = value.
If it is user and session specific, you could always store it in a session. It's simple as: Session["VarName"] = object;
You can use the HttpContext to store items that need to be accessed throughout the lifecycle.
Example:
HttpContext.Items["myVariableKey"] = "my value";
The item put into that collection are only available for the current request.
I have an idea that reading values from config files instead of using hard code values, but I'm not sure it is a good practice or not.
First I created a utility class:
public class ConfigValues
{
public static int Read(string key, int defaultValue){....}
public static string Read(string key, string defaultValue){....}
public static bool Read(string key, bool defaultValue){....}
...
}
The Read function tries to read value for the given key. If the key doesnot exist or the value has bad format, it returns the default value. And I'm going to use this class like:
public class MyClass
{
private int _age = ConfigValues.Read("Com.MyClass.Age", 0);
...
}
So that, we can make almost all variables in the application customizable.
Will it be a good practice?
Please comment it for free.
People who think you should make things configurable:
Some of the other answers
http://www.ebizq.net/blogs/decision_management/2007/04/dont_softcode_use_business_rul.php
Many good software development theories (I don't have links handy).
People who think differently:
http://ayende.com/Blog/archive/2008/08/21/Enabling-change-by-hard-coding-everything-the-smart-way.aspx (And the rest of his entries)
http://thedailywtf.com/Articles/Soft_Coding.aspx
http://benbro.com/blog/on-configuration/
http://jeffreypalermo.com/blog/hardcoding-considered-harmful-or-is-it/
The answer comes down to your requirements: why are you setting this value here?
Is it something that different users will want set differently? => config file.
Is it just a default value to be changed later? => Hardcode it.
Is it something which affects operational use of the program (i.e. default homepage for browser)? => Config file.
Is it something which might have complex impacts on various parts of the program? ... Answer depends on your userbase.
Etc. It's not a simple yes-it's-good or no-it's-bad answer.
Configuration files are always a good idea.
Think of the INI files, for example.
It would be immensely useful to introduce a version numbering scheme in your config files.
So you know what values to expect in a file and when to look for defaults when these are not around. You might have hardcoded defaults to be used when the configurations are missing from the config file.
This gives you flexibility and fallback.
Also decide if you will be updating the file from your application.
If so, you need to be sure it can manage the format of the file.
You might want to restrict the format beforehand to make life simpler.
You could have CSV files or "name=value" INI style files.
Keep it simple for your code and the user who will edit them.
Configuration file also allow you to update the values without doing another build to change a single value. This can be useful to have one build for all environments, with different configuration values (log levels, user names, etc.). Also, if you cache the values and periodically update from the file, it allows you to make changes on the fly while the application is still running. This may be overkill in some situations, but it can be very helpful in debugging certain issues.
Do:
Create a new C# project
Menu->Project->[Project name] Properties
Open Settings pane
Create your settings (it's strongly typed)
Usage:
class Program
{
static void Main(string[] args)
{
int setting1 = Properties.Settings.Default.Setting1;
Properties.Settings.Default.Setting1 = 43534;
Proerties.Settings.Default.Save();
}
}
Note that Properties is a namespace and you can import it so you can use Settings.Default.Setting1.
Here is a more detailed link.
If you use a windows forms application, you could change the Program.cs file to save all the changed settings when leaving application:
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
//Add this line
Application.ApplicationExit +=
new EventHandler(Application_ApplicationExit);
Application.Run(new Form1());
}
//and this method:
static void Application_ApplicationExit(object sender, EventArgs e)
{
Properties.Settings.Default.Save();
}
}
I have a console application that I am rebuilding from C to C#. This application has to be able to support the legacy method of storing information like parameters from a command-line and parameters from a file (called the system parameters) that customize each run. The system parameters file is in plain-text with a simple key-value structure.
My questions are:
Should I combine these different parameters into a single Configuration object?
How would I call this configuration object from the code to store parameters?
How would I call this configuration object from the code to retrieve parameters?
Should this object be strongly-typed?
I will need access to this structure from a lot of different places in the code. What is the most elegant way to retrieve the values in the object without passing the object itself around everywhere?
I have a feeling that it should be a single, strongly-typed object and that it should be an instantiated object that is retrieved from a repository with a static retrieval method however I really want validation of this method.
I would use a single configuration object like the following:
using System;
using System.IO;
using System.Reflection;
public sealed class Setting {
public static int FrameMax { get; set; }
public static string VideoDir { get; set; }
static readonly string SETTINGS = "Settings.ini";
static readonly Setting instance = new Setting();
Setting() {}
static Setting() {
string property = "";
string[] settings = File.ReadAllLines(SETTINGS);
foreach (string s in settings)
try {
string[] split = s.Split(new char[] { ':' }, 2);
if (split.Length != 2)
continue;
property = split[0].Trim();
string value = split[1].Trim();
PropertyInfo propInfo = instance.GetType().GetProperty(property);
switch (propInfo.PropertyType.Name) {
case "Int32":
propInfo.SetValue(null, Convert.ToInt32(value), null);
break;
case "String":
propInfo.SetValue(null, value, null);
break;
}
} catch {
throw new Exception("Invalid setting '" + property + "'");
}
}
}
Since this is a singleton, it will create one and only one instance of itself the first time a public static property is referenced from the Setting object.
When the object is created, it reads from the Settings.ini file. The settings file is a plain-text file with a simple key : value structure that might look like this:
FrameMax : 12
VideoDir : C:\Videos\Best
The object uses reflection to discover each property and to store its initial value. In this example, two properties have been defined:
public static int FrameMax { get; set; }
public static string VideoDir { get; set; }
The code as written handles Int32 and String types. By adding additional case statements to the switch statement, you could easily add support for types like Float and Decimal.
To change a setting, you would use something like:
Setting.FrameMax = 5;
To retrieve a setting, you would use something like:
if (Setting.FrameMax > 10) ...
You'll notice that all the properties are strongly-typed. Also, you don't have to pass the Setting object around, as all the Setting properties are static and always available everywhere.
I hope this idea is helpful.
I like using Settings. These can be generated automatically either by creating a settings file using the Add New File dialog box, or by adding a default settings file from project properties.
Each setting may be in user or application scope, which controls whether or not the user can change them or they are restricted to their default values. They are easily saved with the Save() method and loaded automatically into the static Default property.
This class seems to be for application or user-based settings. I'm looking for per-run settings. Would you still recommend using this class in that case? – x97mdr
Yes. If you have both user/application based settings and per-run settings you should use two different classes - the normal (saved) settings and the per-run settings.
As long as you don't save the per-run settings, you should be safe and settings are still quite easy to use. These are static settings though. If the same application run needs several instances - this is the wrong approach.
I find that whenever I have to deal with a legacy system, sticking with the old format almost always works best. Often times there are other people using the legacy formats for other tasks (like automation of the app, for example), so if you recode the way the application handles inputs, you might break other systems.
On the other hand, if you are pretty confident that you know all the people using the system, and they tell you that they don't care if you change these types of things, I would probably move everything to XML. Besides all the nice features of XML from an application point of view (like being in ASCII so it's easily modified by humans, being self-documenting, etc ...), XML is also time-saving, in that you don't have to write your own I/O or parser. There's already a wide variety of libraries out there, particularly in .NET 3.0/3.5, that do very well. (As you're moving to C#, I'm guessing you're already thinking along these lines :)
So ultimately, you'd have to base your decision on cost-to-implement: if you lower your cost of implementation by moving to XML or similar, make sure that you don't raise other people's cost of implementation to move to your new application framework.
Good luck!
XmlDocument - you can generate a class definition using XSD.exe