views:

357

answers:

6

Hi,

I'm really confused by the various configuration options for .Net configuration of dll's, ASP.net websites etc in .Net v2 - especially when considering the impact of a config file at the UI / end-user end of the chain.

So, for example, some of the applications I work with use settings which we access with:

string blah = AppLib.Properties.Settings.Default.TemplatePath;

Now, this option seems cool because the members are stongly typed, and I won't be able to type in a property name that doesn't exist in the Visual Studio 2005 IDE. We end up with lines like this in the App.Config of a command-line executable project:

  <connectionStrings>
      <add name="AppConnectionString" connectionString="XXXX" />
      <add name="AppLib.Properties.Settings.AppConnectionString" connectionString="XXXX" />
  </connectionStrings>

(If we don't have the second setting, someone releasing a debug dll to the live box could have built with the debug connection string embedded in it - eek)

We also have settings accessed like this:

string blah = System.Configuration.ConfigurationManager.AppSettings["TemplatePath_PDF"];

Now, these seem cool because we can access the setting from the dll code, or the exe / aspx code, and all we need in the Web or App.config is:

  <appSettings>
    <add key="TemplatePath_PDF" value="xxx"/>
  </appSettings>

However, the value of course may not be set in the config files, or the string name may be mistyped, and so we have a different set of problems.

So... if my understanding is correct, the former methods give strong typing but bad sharing of values between the dll and other projects. The latter provides better sharing, but weaker typing.

I feel like I must be missing something. For the moment, I'm not even concerned with the application being able to write-back values to the configuration files, encryption or anything like that. Also, I had decided that the best way to store any non-connection strings was in the DB... and then the very next thing that I have to do is store phone numbers to text people in case of DB connection issues, so they must be stored outside the DB!

A: 

I think your confusion comes from the fact that it looks like your first example is a home-brewed library, not part of .NET. The configurationmanager example is an example of built-in functionality.

Geoffrey Chetwood
A: 

Hi Rich,

The code sample I provided to access the library settings:

string blah = AppLib.Properties.Settings.Default.TemplatePath;

uses code generated by the .Net compiler (based on use of the Properties|Settings section of a dll project) - so it is built-in / framework functionality I believe.

Nij
+2  A: 

If you use the settings tab in VS 2005+, you can add strongly typed settings and get intellisense, such as in your first example.

string phoneNum = Properties.Settings.Default.EmergencyPhoneNumber;

This is physically stored in App.Config.

You could still use the config file's appSettings element, or even roll your own ConfigurationElementCollection, ConfigurationElement, and ConfigurationSection subclasses.

As to where to store your settings, database or config file, in the case of non-connection strings: It depends on your application architecture. If you've got an application server that is shared by all the clients, use the aforementioned method, in App.Config on the app server. Otherwise, you may have to use a database. Placing it in the App.Config on each client will cause versioning/deployment headaches.

rob_g
A: 

I support Rob Grays answer, but wanted to add to it slightly. This may be overly obvious, but if you are using multiple clients, the app.config should store all settings that are installation specific and the database should store pretty much everything else.

Single client (or server) apps are somewhat different. Here it is more personal choice really. A noticable exception would be if the setting is the ID of a record in the database, in which case I would always store the setting in the database with a foreign key to ensure the reference doesn't get deleted.

Dr8k
A: 

Yes - I think I / we are in the headache situation Rob descibes - we have something like 5 or 6 different web-sites and applications across three independent servers that need to access the same DB. As things stand, each one has its own Web or App.config with the settings described setting and / or overriding settings in our main DB-access dll library.

Rob - when you say application server, I'm not sure what you mean? The nearest thing I can think is that we could at least share some settings between sites on the same machine by putting them in a web.config higher in the directory hierarchy... but this too is not something I've been able to investigate... having thought it more important to understand which of the strong or weak-typed routes is 'better'.

Nij
+1  A: 

Nij, our difference in thinking comes from our different perspectives. I'm thinking about developing enterprise apps that predominantly use WinForms clients. In this instance the business logic is contained on an application server. Each client would need to know the phone number to dial, but placing it in the App.config of each client poses a problem if that phone number changes. In that case it seems obvious to store application configuration information (or application wide settings) in a database and have each client read the settings from there.

The other, .NET way, (I make the distinction because we have, in the pre .NET days, stored application settings in DB tables) is to store application settings in the app.config file and access via way of the generated Settings class.

I digress. Your situation sounds different. If all different apps are on the same server, you could place the settings in a web.config at a higher level. However if they are not, you could also have a seperate "configuration service" that all three applications talk to get their shared settings. At least in this solution you're not replicating the code in three places, raising the potential of maintenance problems when adding settings. Sounds a bit over engineered though.

My personal preference is to use strong typed settings. I actually generate my own strongly typed settings class based on what it's my settings table in the database. That way I can have the best of both worlds. Intellisense to my settings and settings stored in the db (note: that's in the case where there's no app server).

I'm interested in learning other peoples strategies for this too :)

rob_g
@rob_g A belated thanks and 'accepted answer' for your comments here. I did end up creating a Setting DB table with one-row per item. I don't think I achieved 'the perfect solution' but it is a lot better than we had before.
Nij