22

Some I do quite a lot of is read integers from AppSettings. What's the best way to do this?

Rather than do this every time:

int page_size; 
if (int.TryParse( ConfigurationManager.AppSettings["PAGE_SIZE"], out page_size){

}

I'm thinking a method in my Helpers class like this:

int GetSettingInt(string key) { 
  int i;
  return int.TryParse(ConfigurationManager.AppSettings[key], out i) ? i : -1;
}

but this is just to save some keystrokes.

Ideally, I'd love to put them all into some kind of structure that I could use intellisense with so I don't end up with run-time errors, but I don't know how I'd approach this... or if this is even possible.

What's a best practices way of getting and reading integers from the AppSettings section of the Web.Config?

ONE MORE THING...

wouldn't it be a good idea to set this as readonly?

readonly int pageSize = Helpers.GetSettingInt("PAGE_SIZE") doesn't seem to work.

Armstrongest
  • 15,181
  • 13
  • 67
  • 106

4 Answers4

24

I've found an answer to my problem. It involves extra work at first, but in the end, it will reduce errors.

It is found at Scott Allen's blog OdeToCode and here's my implementation:

Create a static class called Config

public static class Config {

   public static int PageSize {
       get { return int.Parse(ConfigurationManager.AppSettings["PAGE_SIZE"]); }
   }
   public static int HighlightedProductId {
     get { 
      return int.Parse(ConfigurationManager.AppSettings["HIGHLIGHT_PID"]); 
     }
   }
}

Advantage of doing this are three-fold:

  • Intellisense
  • One breakpoint (DRY)
  • Since I only am writing the Config String ONCE, I do a regular int.Parse.

If someone changes the AppSetting Key, it will break, but I can handle that, as those values aren't changed and the performance is better than a TryParse and it can be fixed in one location.

The solution is so simple... I don't know why I didn't think of it before. Call the values like so:

Config.PageSize

Config.HighlightedProductId

Yay!

Armstrongest
  • 15,181
  • 13
  • 67
  • 106
  • While this does seem to be the best way of handling this particular problem, I don't know that you can call this DRY. Every new integer you add requires both a `Web.Config` key and a `Config` class property. If you don't need the power of the `Web.Config` transforms (unlikely, cause they're useful), you could put them all directly in the Config/Constants class, and skip the need to int.Parse() – arserbin3 May 01 '14 at 19:46
  • 1
    What if the user puts a string in the app setting? This would throw an exception, and there is no exception handling or default setting. – SharpC Oct 01 '14 at 15:26
3

I know that this question was asked many years ago, but maybe this answer could be useful for someone. Currently, if you're already receiving an IConfiguration reference in your class constructor, the best way to do it is using GetValue<int>("appsettings-key-goes-here"):

public class MyClass
{
    private readonly IConfiguration _configuration;

    public MyClass(IConfiguration configuration)
    {
        _configuration = configuration;
    }

    public void MyMethod()
    {
        int value = _configuration.GetValue<int>("appsettings-key-goes-here");
    }
}
Luiz Lelis
  • 468
  • 7
  • 11
0

Take a look at T4Config. I will generate an interface and concrete implementation of your appsettings and connectionstringsections of you web/app config using Lazyloading of the values in the proper data types. It uses a simple T4 template to auto generate things for you.

Ryan Anderson
  • 937
  • 10
  • 23
-2

To avoid creating a bicycle class you could use the following:

System.Configuration.Abstractions.AppSettings.AppSetting<int>("intKey");

https://github.com/davidwhitney/System.Configuration.Abstractions

ruffin
  • 16,507
  • 9
  • 88
  • 138