I wrote a class library in C# that uses a external XML file to store some data. I use this data (encoded rules) directly in the class library to do some substitutions within a text parser. The rules within the XML:
<rule>
<word>h e l l o</word>
<sub>Hello</sub>
</rule>
When I share the lib, I also have to share the XML. This is a bug source, at least for me ;) My question: is there any common way to solve such issues? Should I use app.config instead?
Thanks for any hint and best regards!
Why not embed the XML within the dll?
As with every external configuration data i can be changed or missing. So your application (or library) has to deal with such circumstances.
This means:
For every missing value you have a default value (should be declared in your documentation)
Check every value for correctness (type, range, etc.) (All input is evil!)
Blame user for invalid config files (error message, etc)
Implement and document behaviour in error case (abort, crash, use default value, etc)
So it doesn't matter which way to go, cause it is a user configuration (which means it can be changed by the user) and so you have to check those entries.
Create the XML file with default settings/values if it doesn´t exist.
Related
I have implemented a custom file configuration, that uses custom sections, using C#.
The main issue i have is with implementing some kind of version aware configuration loader.
Confgiurations change, but we need to make them usable anyway.
Is there any documentation that points in the direction of having some kind of versioning in configurations?
I'll give you two examples on what my issues are:
- key["key1"] changes from boolean type to int type.
- key["key2"] mandatory ceases to exist
thanks.
My tendency would be to add some kind of version header to the configs and keep a history of their schemas in the app. It could be troublesome in some ways, but at least you don't have to guess what an old value meant.
You could have the concept of default values for each setting. If you introduce a new setting and an old config file doesn't have it then it would use the default value. Similarly, if you remove a setting from the code then its existence in the config file would be harmless, it would just be ignored.
If you want to change how a given setting works (the type or the format) then it's a little more tricky. You could try to parse the value and if it's not in the right format you could ignore it and use the default value.
I've always used my own format of configuration files which is XML and then I just deserialise the XML into an object in my project or just read it into an XML document.
This seems alot easier to read and access the information I need.
I've had a look at the ConfigurationManager class this morning and it seems a bit overly complicated just to read a config file.
Is there any argument as to why I should use ConfigurationManager?
It is just a built-in mechanism in .NET which is already implemented for you, so you don't need any extra code (probably except for wrapping it in your own IConfig to separate concerns).
There is a GUI for editing .NET configuration files which sometimes comes in handy.
ASP.NET application, for instance, automatically restart when web.config has been changed, while you would need some custom logic to have the same behaviour with your own config files.
The ConfigurationManager is used internally and you're not obligated in any way to use it, and I used to do what you do. Nowadays it depends, if it is a file a user is supposed to change I might still do my own configuration, otherwise the file is added as an embedded resource and I use the ConfigurationManager to read it, because I don't think there is another way of reading those files. The thing is, use whatever mechanism you feel like, ConfigurationManager provides a bit more encapsulation though and out of the box utils classes.
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.
I was wondering if anyone had any input on the best practice of where to store static error strings in a C# application. I have a visual studio 2010 solution that has 5 projects and have defined several constant error messages to be returned via a WCF REST web service in the form of a message.
My current errors I have defined (hard-coded) are in the following format (CODE, MESSAGE):
999 - Your request could not be processed with the parameters specified.
I am not asking how to create custom classes derived from the Exception class because these errors are returned after corresponding Exceptions are raised to keep the AppPool from faulting.
Some ideas I was pondering storing the messages in: XML, Flat File, SQLite, and so on.
Does anyone have a preference and if so, why?
Thank you,
Jeffrey Kevin Pry
I personally store these things in the projects Resources file, and then retrieve them when I need them. Doing it this way also makes it a lot easier to change them, for example if you needed the system to use another language all you'd do is switch the resources file for one in another language and voila!
I've begun to the the built-in TraceSource and TraceListener classes and I would like to modify the output format of the events independently of the TraceSources and TraceListeners. It seems that the TraceListeners apply their own formatting. Is it possible to completely change the formatting without creating a new class for each and every TraceListener I use?
The Enterprise Library Logging Application Block (http://msdn.microsoft.com/en-us/library/cc309506.aspx) is built on the .Net TraceSource and TraceListener classes (so you can pretty much just drop it into your project and it'll work), and it supports a message formatter that you can configure in the web.config (or app.config).
This is way late, but for any latecomers who might be looking for a TraceSource/TraceListener solution that supports formatting similar to that available in log4net, NLog, and LAB, you might try Ukadc.Diagnostics. You can configure the Ukadc-provided TraceListeners with a formatting string, and it will be applied when traces are written to the listener. You can also write your own tokens and add them to the formatting statement. For example, I wrote one for fun that simply increments a counter each time its value is retrieved. The result is that in the log file, each line receives a sequentially increasing number. I wrote another one that allows information from Trace.CorrelationManager.LogicalOperationStack to be added to the output.
I don't have easy access right now to my computer that has that work on it, or I would post these examples.
You can use the direct Write() or WriteLine() methods on Trace to put straight text into your TraceListener.
For anyone who ends up here and is still looking for custom formatting for TraceListeners, there is also Essential.Diagnostics https://essentialdiagnostics.codeplex.com/ (disclosure: I am involved in the project).
To answer the original question a TraceListener can accept custom properties in the configuration, so it is possible to write one TraceListener that handles multiple formats based on configuration, which might be more flexible than writing multiple.
This is what Essential.Diagnostics has, it has both a ColoredConsoleTraceListener and RollingFileTraceListener that support custom format strings, with many format values already available.