This question is too broad to answer it in full. Basically, using data is much more than just avoiding hard-coding. It all depends on your requirements and different architectural option.
Of course, hard-coding of data is very, very bad. But what do you consider data? Your whole program can also be represented in the form of data handled by some other program.
The basic idea is that you cannot do an application which is absolutely universal, unless you model a whole computer in your program and let the users write their own. So, the solutions should be realistic and consider both functional requirements and the provision for flexibility in case of changing requirements. This way, you can understand what to make optional right away and what can rely on next release. In a general architecture, one should focus on identifying, where the knowledge is and where is the right method of expressing the knowledge. Some knowledge is represented in the source code, and this is ultimately unavoidable. This fundamental kind of architectural decisions is one of the difficult parts of work.
The options you've listed also depend on requirements. (However, you probably may forget obsolete INI and avoid plain text, but it should not be an absolutely strict rule.) You should consider them as a mere media for persisting data, not the data. To get better idea on what am I talking about, read about
Data Contract:
http://msdn.microsoft.com/en-us/library/ms733127.aspx[
^].
By the way, this is a best way to persist not very big volumes of data with minimal effort and maximum flexibility at the same time. Please see my past solution advocating this approach:
How can I utilize XML File streamwriter and reader in my form application?[
^],
Creating property files...[
^],
deseralize a json string array[
^].
In this approach, you do not persist any separate data items, you persist the whole object graph of any complexity representing some
data model.
That was about just the data. Now, let's come back on a more general level and talk about the knowledge.
You see, some knowledge is better to express in data, but some — in code.
Respectively, if you need non-monolithic architecture with more flexible possibilities for updates, you need to consider two ways: one is data persistence explain above, another one — pluggable architecture of the code with replaceable components usually called
plug-ins. The plug-ins can even be reloadable.
I overview some of the approaches on my past solutions written in response to different questions. Please see:
Create WPF Application that uses Reloadable Plugins...[
^],
AppDomain refuses to load an assembly[
^],
code generating using CodeDom[
^],
Dynamically Load User Controls[
^].
I won't be surprised that this is a bit over your head. I think that looking at the bigger picture is always useful. You can come back to it some day later.
—SA