views:

454

answers:

6

I am writing a C# application that uses a long "hard-coded" string.

For maintainability reasons I have decided to put this string in an external text file and load it. Is this a good idea? The extra I/O does not seem big in this case.

I realize that I also have an option to embed this file as a .resx resource. Is this a better idea? The file will never need to be localized.

+1  A: 

I would suggest to use Application Settings.

You can follow this MSDN link how to use Application and User Settings.

Vadim
Thanks, see my other comments - I'm not sure how scalable this is
Yaron Naveh
+1  A: 

I would put this in an application configuration file.

Andrew Hare
Thanks, see my other comments - I'm not sure how scalable this is
Yaron Naveh
+1  A: 

Even better would be to add a Settings file to your project. You can then easily add configuration settings through Visual Studio. See this link.

You could then access your string by using the following:

Settings.Default.MyString;

In addition, settings are strongly typed, so you don't need to do any conversions when you retrieve them.

Shane Fulmer
Thanks - see my comment to the other answers, how does this solution fulfills my demands?
Yaron Naveh
+3  A: 

Why not make it an appSetting in your web/app.config file?

<appSettings>
   <add key="MyLongString" value="This is a really long string value that I don't want hardcoded" />
</appSettings>

Then, in code:

using System.Configuration;    //To ease your typing pains

var myReallyLongString = ConfigurationManager.AppSettings["MyLongString"];
AJ
My .dll implements an extensibility point for another application so I'm not allowed to change app.config. Even if I would be - app.config is loaded at startup but my code line may never be called so I don't want this string in memory for no reason.I'm mostly interested in maintainability:- Which option is easiest to maintain?- Which will be best in case I need "production debugging"?- Which if I'll need to have many more files like this?
Yaron Naveh
+9  A: 

If you intend to allow users/administrators to change the string, I agree with the other answers, and I'd suggest putting it in settings.

If you don't want it to be editable after deployment and it will only be modified by you and your developers, then I would put it in an embedded resource (note, this is not the same as a .resx file). You would read it at runtime like this:

Assembly assembly = Assembly.GetExecutingAssembly();
Stream stream = assembly.GetManifestResourceStream(“MyAssemblyNamespace.MyTextFile.txt”);
StreamReader reader = new StreamReader(stream);
string theText = streamReader.ReadToEnd();

Update: This is solution that is easy to maintain. The .txt file will just be another file in your solution explorer in Visual Studio and you can edit it just like any other file, keep it under source control like any other file, etc. To turn it into an embedded resource by changing the Build Action in the properties window to "Embedded Resource".

The end result is that your file(s) get embedded in your DLL so that you only have 1 DLL to distribute instead of a DLL and a folder of files that have to move around together.

Update 2: Regarding "production debugging", this is a very static solution, and so you won't be able to change the contents of the text file at runtime because the file is baked into the DLL at compile time. For reading the contents of the file, you can use tools like reflector to view the embedded resources of a DLL. You could also write a simple command line tool that dumps all the embedded .txt files from a DLL into individual files for you to look at.

For memory usage, there isn't a solution more efficient than "I load it from a file into memory only exactly when it is needed". You have to decide whether the improved maintainability and deployment is worth the cost of a little extra memory when your DLL is loaded into memory for your specific situation. That said, you haven't said how large these files are. If they are really huge (megabytes+), I would probably not use this solution and would go with loose files on the hard drive. If they are generally pretty small (hundreds of kilobytes), I wouldn't worry about the extra memory unless you are in some kind of embedded device situation where RAM is really tight.

Erv Walter
Thanks - see my comment to the other answers, how does this solution fulfills my demands?
Yaron Naveh
Added some comments about maintainability...
Erv Walter
Thanks - but what about:1. "production debugging" - if I have some suspicion that there are version issues isn't it easier for me to open the external text file?2. Let's say the string will become very big and there will also be other strings. With your solution they all go into memory when the dll is loaded and also make its size big. When they are an external file they are only loaded when (and if) I need them.
Yaron Naveh
Yaron, Your objections and concerns don't seem valid. First, you've made a bad assumption. Embedded Resources in an assembly are not all loaded into memory when you load the DLL. Second, what do you mean about "production debugging." Your comments keep mentioning this but you never elaborate on what it means and why it is an obstacle to using embedded resources. The embedded resource still seems the best idea, for reasonably sized strings.
Cheeso
Yaron Naveh
A: 

To more directly answer your question, the "best practice" would be to use a resource file for any localizable (even if you're not going to localize it) string in your application. This allows you compile-time access to the string and keeps it from being externalized as a separate file to deploy with your application.

I suggest using this approach; settings are similar, but should not be used unless what you're storing there actually represents a setting. Constants are the other option, but in the case of a long string, I'd stay away from them, just for the sake of maintainability.

Ed Altorfer