Custom user configuration in C# application - c#

Let's say I have a command line application that needs to reference some form of a user configuration file. Furthermore, the values contained within this file are to only be updated by the user manually -- there won't be any ways of updating the configuration file within the application, nor will the application seek out any inputs once started. If a configuration listing is missing from the configuration file, a default value should be used instead.
I understand that Visual Studio / .NET Framework offer tools for creating such constructs (i.e. Settings and App.configs), but I'm not sure I'm using them correctly -- or if I should be using them at all.
I created a Settings file and threw in a couple of default settings (e.g. SomeBooleanFlag is a bool with a default value of 'False'). This addition of course was reflected within my App.config. However, here is where the dilemma lies: how should I read from the App.config?
Currently, I've created a class to abstract away the configuration manager / settings stuff:
class AppSettings
{
public static bool SomeBooleanFlag
{
get
{
try
{
string rawValue = ConfigurationManager.AppSettings["SomeBooleanFlag"];
bool userSetSomeBooleanFlag;
bool userValueParsed = bool.TryParse(rawValue, out userSetSomeBooleanFlag);
return (userValueParsed) ? userSetSomeBooleanFlag : Settings.Default.SomeBooleanFlag;
}
catch
{
return Settings.Default.SomeBooleanFlag;
}
}
}
}
Which then gives me the ability to write:
if (AppSettings.SomeBooleanFlag)
{
/* Do Something... */
}
However, this does not seem like a clean way to approach the problem I stated above. Any help would be greatly appreciated!

Instead of coding your own Application Settings wrapper, you can reuse the functionality built into Visual Studio to generate this wrapper for you. See How to: Add or Remove Application Settings and How To: Read Settings at Run Time With C#. In addition to specifying the type of the setting you can also indicate the scope (User or Application).
Following the steps in the aforementioned articles, it will add the settings to your App.config file, below is an example:
<configuration>
...
<applicationSettings>
<ConsoleApplication1.Properties.Settings>
<setting name="TestKey" serializeAs="String">
<value>TestValue</value>
</setting>
</ConsoleApplication1.Properties.Settings>
</applicationSettings>
...
</configuration>
And you can access these settings as follows:
string s = Properties.Settings.Default.TestKey;

Related

How to read the custom configuration settings in c#? [duplicate]

I'm working on a C# class library that needs to be able to read settings from the web.config or app.config file (depending on whether the DLL is referenced from an ASP.NET web application or a Windows Forms application).
I've found that
ConfigurationSettings.AppSettings.Get("MySetting")
works, but that code has been marked as deprecated by Microsoft.
I've read that I should be using:
ConfigurationManager.AppSettings["MySetting"]
However, the System.Configuration.ConfigurationManager class doesn't seem to be available from a C# Class Library project.
What is the best way to do this?
For a sample app.config file like below:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="countoffiles" value="7" />
<add key="logfilelocation" value="abc.txt" />
</appSettings>
</configuration>
You read the above application settings using the code shown below:
using System.Configuration;
You may also need to also add a reference to System.Configuration in your project if there isn't one already. You can then access the values like so:
string configvalue1 = ConfigurationManager.AppSettings["countoffiles"];
string configvalue2 = ConfigurationManager.AppSettings["logfilelocation"];
You'll need to add a reference to System.Configuration in your project's references folder.
You should definitely be using the ConfigurationManager over the obsolete ConfigurationSettings.
Update for .NET Framework 4.5 and 4.6; the following will no longer work:
string keyvalue = System.Configuration.ConfigurationManager.AppSettings["keyname"];
Now access the Setting class via Properties:
string keyvalue = Properties.Settings.Default.keyname;
See Managing Application Settings for more information.
Right click on your class library, and choose the "Add References" option from the Menu.
And from the .NET tab, select System.Configuration. This would include the System.Configuration DLL file into your project.
I'm using this, and it works well for me:
textBox1.Text = ConfigurationManager.AppSettings["Name"];
Read From Config:
You'll need to add a reference to the configuration:
Open "Properties" on your project
Go to "Settings" Tab
Add "Name" and "Value"
Get Value with using following code:
string value = Properties.Settings.Default.keyname;
Save to the configuration:
Properties.Settings.Default.keyName = value;
Properties.Settings.Default.Save();
You must add a reference to the System.Configuration assembly to the project.
You might be adding the App.config file to a DLL file. App.Config works only for executable projects, since all the DLL files take the configuration from the configuration file for the EXE file being executed.
Let's say you have two projects in your solution:
SomeDll
SomeExe
Your problem might be related to the fact that you're including the app.config file to SomeDLL and not SomeExe. SomeDll is able to read the configuration from the SomeExe project.
Try this:
string keyvalue = System.Configuration.ConfigurationManager.AppSettings["keyname"];
In the web.config file this should be the next structure:
<configuration>
<appSettings>
<add key="keyname" value="keyvalue" />
</appSettings>
</configuration>
Step 1: Right-click on references tab to add reference.
Step 2: Click on Assemblies tab
Step 3: Search for 'System.Configuration'
Step 4: Click OK.
Then it will work.
string value = System.Configuration.ConfigurationManager.AppSettings["keyname"];
I had the same problem. Just read them this way:
System.Configuration.ConfigurationSettings.AppSettings["MySetting"]
web.config is used with web applications. web.config by default has several configurations required for the web application. You can have a web.config for each folder under your web application.
app.config is used for Windows applications. When you build the application in Visual Studio, it will be automatically renamed to <appname>.exe.config and this file has to be delivered along with your application.
You can use the same method to call the app settings values from both configuration files:
System.Configuration.ConfigurationSettings.AppSettings["Key"]
As I found the best approach to access application settings variables in a systematic way by making a wrapper class over System.Configuration as below
public class BaseConfiguration
{
protected static object GetAppSetting(Type expectedType, string key)
{
string value = ConfigurationManager.AppSettings.Get(key);
try
{
if (expectedType == typeof(int))
return int.Parse(value);
if (expectedType == typeof(string))
return value;
throw new Exception("Type not supported.");
}
catch (Exception ex)
{
throw new Exception(string.Format("Config key:{0} was expected to be of type {1} but was not.",
key, expectedType), ex);
}
}
}
Now we can access needed settings variables by hard coded names using another class as below:
public class ConfigurationSettings:BaseConfiguration
{
#region App setting
public static string ApplicationName
{
get { return (string)GetAppSetting(typeof(string), "ApplicationName"); }
}
public static string MailBccAddress
{
get { return (string)GetAppSetting(typeof(string), "MailBccAddress"); }
}
public static string DefaultConnection
{
get { return (string)GetAppSetting(typeof(string), "DefaultConnection"); }
}
#endregion App setting
#region global setting
#endregion global setting
}
Also, you can use Formo:
Configuration:
<appSettings>
<add key="RetryAttempts" value="5" />
<add key="ApplicationBuildDate" value="11/4/1999 6:23 AM" />
</appSettings>
Code:
dynamic config = new Configuration();
var retryAttempts1 = config.RetryAttempts; // Returns 5 as a string
var retryAttempts2 = config.RetryAttempts(10); // Returns 5 if found in config, else 10
var retryAttempts3 = config.RetryAttempts(userInput, 10); // Returns 5 if it exists in config, else userInput if not null, else 10
var appBuildDate = config.ApplicationBuildDate<DateTime>();
If your needing/wanting to use the ConfigurationManager class...
You may need to load System.Configuration.ConfigurationManager by Microsoft via NuGet Package Manager
Tools->NuGet Package Manager->Manage NuGet Packages for Solution...
Microsoft Docs
One thing worth noting from the docs...
If your application needs read-only access to its own configuration,
we recommend that you use the GetSection(String) method. This method
provides access to the cached configuration values for the current
application, which has better performance than the Configuration
class.
I strongly recommend you to create a wrapper for this call. Something like a ConfigurationReaderService and use dependency injection to get this class. This way you will be able to isolate this configuration files for test purposes.
So use the ConfigurationManager.AppSettings["something"]; suggested and return this value. With this method you can create some kind of default return if there isn't any key available in the .config file.
Just for completeness, there's another option available for web projects only:
System.Web.Configuration.WebConfigurationManager.AppSettings["MySetting"]
The benefit of this is that it doesn't require an extra reference to be added, so it may be preferable for some people.
I always create an IConfig interface with typesafe properties declared for all configuration values. A Config implementation class then wraps the calls to System.Configuration. All your System.Configuration calls are now in one place, and it is so much easier and cleaner to maintain and track which fields are being used and declare their default values. I write a set of private helper methods to read and parse common data types.
Using an IoC framework you can access the IConfig fields anywhere your in application by simply passing the interface to a class constructor. You're also then able to create mock implementations of the IConfig interface in your unit tests so you can now test various configuration values and value combinations without needing to touch your App.config or Web.config file.
Please check the .NET version you are working on. It should be higher than 4. And you have to add the System.Configuration system library to your application.
You can use the below line. In my case it was working:
System.Configuration.ConfigurationSettings.AppSettings["yourKeyName"]
You must take care that the above line of code is also the old version and it's deprecated in new libraries.
The ConfigurationManager is not what you need to access your own settings.
To do this you should use
{YourAppName}.Properties.Settings.{settingName}
I was able to get the below approach working for .NET Core projects:
Steps:
Create an appsettings.json (format given below) in your project.
Next create a configuration class. The format is provided below.
I have created a Login() method to show the usage of the Configuration Class.
Create appsettings.json in your project with content:
{
"Environments": {
"QA": {
"Url": "somevalue",
"Username": "someuser",
"Password": "somepwd"
},
"BrowserConfig": {
"Browser": "Chrome",
"Headless": "true"
},
"EnvironmentSelected": {
"Environment": "QA"
}
}
public static class Configuration
{
private static IConfiguration _configuration;
static Configuration()
{
var builder = new ConfigurationBuilder()
.AddJsonFile($"appsettings.json");
_configuration = builder.Build();
}
public static Browser GetBrowser()
{
if (_configuration.GetSection("BrowserConfig:Browser").Value == "Firefox")
{
return Browser.Firefox;
}
if (_configuration.GetSection("BrowserConfig:Browser").Value == "Edge")
{
return Browser.Edge;
}
if (_configuration.GetSection("BrowserConfig:Browser").Value == "IE")
{
return Browser.InternetExplorer;
}
return Browser.Chrome;
}
public static bool IsHeadless()
{
return _configuration.GetSection("BrowserConfig:Headless").Value == "true";
}
public static string GetEnvironment()
{
return _configuration.GetSection("EnvironmentSelected")["Environment"];
}
public static IConfigurationSection EnvironmentInfo()
{
var env = GetEnvironment();
return _configuration.GetSection($#"Environments:{env}");
}
}
public void Login()
{
var environment = Configuration.EnvironmentInfo();
Email.SendKeys(environment["username"]);
Password.SendKeys(environment["password"]);
WaitForElementToBeClickableAndClick(_driver, SignIn);
}
Another possible solution:
var MyReader = new System.Configuration.AppSettingsReader();
string keyvalue = MyReader.GetValue("keyalue",typeof(string)).ToString();
I have been trying to find a fix for this same issue for a couple of days now. I was able to resolve this by adding a key within the appsettings tag in the web.config file. This should override the .dll file when using the helper.
<configuration>
<appSettings>
<add key="loginUrl" value="~/RedirectValue.cshtml" />
<add key="autoFormsAuthentication" value="false"/>
</appSettings>
</configuration>
extra : if you are working on a Class Library project you have to embed the settings.json file.
A class library shouldn't really be directly referencing anything in
app.config - the class doesn't have an app.config, because it's not an
application, it's a class.
Go to the JSON file's properties.
Change Build Action -> Embedded resource.
Use the following code to read it.
var assembly = Assembly.GetExecutingAssembly();
var resourceStream = assembly.GetManifestResourceStream("Assembly.file.json");
string myString = reader.ReadToEnd();
now we have a JSON string we can Deserialize it using JsonConvert
if you didn't embed the file inside the assembly you can't use only the DLL file without the file
I'm using Visual Studio for Mac version 17.0.6.
As you can see on this screenshot it is not possible to add a reference to System.Configuration.
Solution:
install NuGet Package - System.Configuration.ConfigurationManager.
Create app.config file and set "Build action" to "EmbeddedResource"
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="name" value="Joe"/>
</appSettings>
</configuration>
using System.Configuration;
enjoy)
string name = ConfigurationManager.AppSettings["name"];
BTW: Do not add an app.config for a library
I found the answer in this link https://stackoverflow.com/a/1836938/1492229
It's not only necessary to use the namespace System.Configuration. You have also to add the reference to the assembly System.Configuration.dll , by
Right-click on the References / Dependencies
Choose Add Reference
Find and add System.Configuration.
This will work for sure.
Also for the NameValueCollection you have to write:
using System.Collections.Specialized;
Here's an example: App.config
<applicationSettings>
<MyApp.My.MySettings>
<setting name="Printer" serializeAs="String">
<value>1234 </value>
</setting>
</MyApp.My.MySettings>
</applicationSettings>
Dim strPrinterName as string = My.settings.Printer

Elegant solution to read application settings by parsing xml file (app.config)

I am reading the app.config settings by a seperate project using a xml reader. The app.config can not be read by Properties.Settings.Default.MySetting in a different dll. Now I am trying to finde a proper Solution how to read different settings in different formats (StringCollection, String, ...).
https://imgur.com/a/AxeCTsC
(For all who ask why I do not read the information in the TestConsole like this:
var sc = Properties.Settings.Default.PathToPython;
That is because I reuse the projects. In this case I have a TestConsole and I will add service application. The TestConsole app is just for developing. But I donĀ“t want to copy my code from one to another app. The TestConsol or later the service app gets as minimal code as possible.
a part of the app.config looks like this:
<applicationSettings>
<ToolkitConnector.Ui.TestConsole.Properties.Settings>
<setting name="PythonApp" serializeAs="String">
<value>status.py</value>
</setting>
<setting name="PathToPython" serializeAs="String">
<value>python</value>
</setting>
<setting name="OutputFolder" serializeAs="String">
<value>c:\toolkit_1\status\statusOfPlatform1\</value>
</setting>
<setting name="PySkriptWorkingDirectory" serializeAs="String">
<value>c:\toolkit_1\</value>
</setting>
<setting name="LgInInformation" serializeAs="Xml">
<value>
<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<string>User1</string>
<string>Pwd1</string>
<string>GER_PROD</string>
<string>18701</string>
<string>Technology1</string>
<string>User2</string>
<string>Pwd2</string>
<string>GER_PROD</string>
<string>18795</string>
<string>Technology2</string>
</ArrayOfString>
</value>
</setting>
</ToolkitConnector.Ui.TestConsole.Properties.Settings>
In my project Logic.ControlAppSetting I use that code to read the xml file
public void GetApplicationSetting(string path)
{
XmlDocument doc = new XmlDocument();
try
{
doc.Load(path);
XmlElement root = doc.DocumentElement;
var applicationSettings = root.SelectSingleNode("applicationSettings");
var mySettings = applicationSettings.SelectSingleNode("ToolkitConnector.Ui.TestConsole.Properties.Settings");
foreach (XmlNode node in mySettings)
{
var test = node.Attributes;
}
}
catch { }
}
Now I am looking for a elegant solution to store the settings information in variables. My problem is that I have different types like StringCollection and String. May be there is a better way to store this information?
Thanks a lot
EDIT:
What I also tried:
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
ConfigurationSectionGroup userSettings = config.GetSectionGroup("applicationSettings");
ClientSettingsSection settings = (ClientSettingsSection)userSettings.Sections.Get("Ui.TestConsole.Properties.Settings");
SettingElement elem = settings.Settings.Get("LgInInformation");
The easiest solution is not to make other libraries depend directly on this file or the auto-generated Settings class that's used to read its values. Your library doesn't need the file or the class. It just needs the values.
If your library depends on reading this file then it can only work in an environment where that file is present. That will make it difficult to use. Typically we can just add a reference to a library and use it. But if the library depends on this file then we would have to modify the application that uses the library to include these settings.
It's also going to make it difficult or impossible to write unit tests for your library. You'd have to add all of those settings to your unit test project too. But what if you want to write tests for the library using two different settings? That would be painful.
Instead, define an environment-agnostic class that contains exactly the settings this library needs.
In its simplest form,
public class MyLibraryConfigurationSettings
{
public string PythonApp { get; set; }
public List<string> LgInInformation { get; } = new List<string>();
}
Then write your library so that in order to use it, the calling app must provide those settings.
Now you're done on the library side of it. In order to use it, you have to give it what it needs. It doesn't know or care where those values come from. It doesn't know if there's a configuration file or where it is.
Now your application must provide it to the library. It can do so by creating an instance of that class and populating it using Properties.Settings.Default.MySetting. Or it can populate it some other way. Now your application isn't forced to use that file either.
Another benefit of this approach is that it makes the requirement more explicit. For example, you can create your library so that adding it to your application requires providing the configuration values. For example, many libraries provide extensions for registering themselves with an IServiceCollection. You could do this:
services.AddYourLibrary(MyLibraryConfigurationSettings settings);
It's immediately clear that this is what the application must provide. You can make it easier by providing a class that can be easily deserialized.
If you depend on the file that relationship is less clear. You could add a reference to the library, write some code, and everything looks good. Then at runtime it throws an exception saying "Where's the file?" and the developer says, "What file?" and they have to look for documentation describing exactly how that file must be defined. It will be even more complicated if the file must be created using the <applicationSettings> section.

ConfigurationManager.AppSettings Returns Null In Unit Test Project

I have a C# unit test project with application settings in the app.config file. I am testing a class that exists in a different project. That class depends on both, ConfigurationManager.AppSettings and ConfigurationManager.ConnectionStrings.
The project that the class being tested resides in does not have an app.config file. I would have thought that because the class is being instantiated in the context of the unit test project that it would use the unit test project's app.config file. Indeed, that does seem to be the case for the connection string.
The class retrieves the connection string without any issues. However, when the class tries to retrieve any application settings the configuration manager always returns null. What is going on here?
Edit 1
I thought maybe it would be a good idea to try load some settings in the test project to see what happens. I tried to load the setting in the unit test immediately before calling the code that instantiates the class in the external project. Same result, nothing. I guess I can exclude the other project from the equation for the time being.
Here is an excerpt from my config file:
<configSections>
<sectionGroup name="applicationSettings"
type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="MyNamespace.Properties.Settings"
type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
requirePermission="false" />
</sectionGroup>
</configSections>
...
<applicationSettings>
<MyNamespace.Properties.Settings>
<setting name="Bing_Key"
serializeAs="String">
<value>...</value>
</setting>
</MyNamespace.Properties.Settings>
</applicationSettings>
and here is how I am attempting to load the setting:
string test = System.Configuration.ConfigurationManager.AppSettings["Bing_Key"];
Consider refactoring your code that accesses the config to use a wrapper. Then you can write mocks for the wrapper class and not have to deal with the importing of the configuration file for the test.
In a library that is common to both, have something like this:
public interface IConfigurationWrapper {
string GetValue(string key);
bool HasKey(string key);
}
Then, in your libraries that need to access config, inject an instance of this interface type into the class that needs to read config.
public class MyClassOne {
private IConfigurationWrapper _configWrapper;
public MyClassOne(IConfigurationWrapper wrapper) {
_configWrapper = wrapper;
} // end constructor
public void MethodThatDependsOnConfiguration() {
string configValue = "";
if(_configWrapper.HasKey("MySetting")) {
configValue = _configWrapper.GetValue("MySetting");
}
} // end method
} // end class MyClassOne
Then, in one of your libraries, create an implementation that depends on the config file.
public class AppConfigWrapper : IConfigurationWrapper {
public string GetValue(string key) {
return ConfigurationManager.AppSettings[key];
}
public bool HasKey(string key) {
return ConfigurationManager.AppSettings.AllKeys.Select((string x) => x.ToUpperInvariant()).Contains(key.ToUpperInvariant());
}
}
Then, in the code that calls your class.
//Some method container
MyClassOne dataClass = new MyClassOne(new AppConfigWrapper());
dataClass.MethodThatDependsOnConfiguration();
Then in your test, you are free from dependency bondage. :) You can either create a fake version that implements IConfigurationWrapper and pass it in for your test, where you hard-code the return values from the GetValue and HasKey functions, or if you're using a mocking library like Moq:
Mock<IConfigurationWrapper> fakeWrapper = new Mock<IConfigurationWrapper>();
fakeWrapper.Setup((x) => x.GetValue(It.IsAny<string>)).Returns("We just bypassed config.");
MyClassOne testObject = new MyClassOne(fakeWrapper.Object);
testObject.MethodThatDependsOnConfiguration();
Here is an article that covers the concept (albeit, for web forms, but the concepts are the same): http://www.schwammysays.net/how-to-unit-test-code-that-uses-appsettings-from-web-config/
You mentioned settings in the project properties. See if you can access the setting this way:
string test = Properties.Settings.Default.Bing_Key;
You may need to get the executing assembly of where the project settings file is defined, but try this first.
EDIT
When using Visual Studio's project settings file, it adds stuff to your app.config and creates the app.config if it is not present. ConfigurationManager CAN'T touch these settings! You can only get to these specific generated project.settings file from using the above static method. If you want to use ConfigurationManager, you will need to hand write your app.config. Add your settings to it like so:
<appSettings>
<add key="bing_api" value="whatever"/>
</appSettings>
If you're using .NET Core your problem could be a known issue caused by the fact that the test process runs as testhost.dll (or testhost.x86.dll), which means the runtime config file is expected to be named "testhost.dll.config" (or "testhost.x86.dll.config"), instead of the app.config output (ex: "MyLibrary.Tests.dll.config").
To fix it, add the code below to your project file (.csproj, etc) inside of root node <Project>. During build, two copies of app.config will be put in the output directory and named "testhost.dll.config" and "testhost.x86.dll.config", which will get your app settings working again. (You only need 1 of these files but it's safer to include both.)
<Target Name="CopyCustomContent" AfterTargets="AfterBuild">
<Copy SourceFiles="app.config" DestinationFiles="$(OutDir)\testhost.dll.config" />
<Copy SourceFiles="app.config" DestinationFiles="$(OutDir)\testhost.x86.dll.config" />
</Target>
I recommend app.config only as a temporary solution. If you're like me you might have run into the problem while upgrading a .NET Framework project to .NET Core and needed a quick fix. But don't forget to look into the new, more elegant solutions provided by .NET Core for storing app settings.
And then he screamed "NOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO".
Cite: I have a C# unit test project with application settings in the app.config file. I am testing a class that exists in a different project. That class depends on both, ConfigurationManager.AppSettings and ConfigurationManager.ConnectionStrings.
You don't do this. EVER!!!! Why? because you have now created a dependency. Instead, use dependency injection so the class can do its work without having to peak into the configuration file that belongs to the application.

Generate an exe with predefinied settings

I do apologise if i didn't asked correctly in the title.. i don't know how to ask or what to call for what i need.
-
Let's say that i have a simple Application called "TestApp" written in C#.
Inside that application, i have the next variables:
int clientid = 123;
string apiurl = "http://somesite/TestApp/api.php";
When i have a new client, i need to create a new special TestApp.exe just for him, changing the 'clientid' variable inside the code.
It's possible to automate this process? To change that variable automatically and export an exe without for me to interfere with the process?
-
I asked this because i think/or i'm sure that it's possible because of the next popular examples:
http://download.cnet.com/2701-20_4-1446.html?tag=sideBar;downloadLinks
[ It creates a special .exe with a predefinied link from where to download the real file ]
http://torrent2exe.com/
[ It's embedding the .torrent file to a special .exe just with some custom variables changed, like torrent name or download size ]
Again, i do apologise if i didn't asked my question correctly and for my bad english, trying my best.
So you have two parts to your question:
You want to have variables inside the program based on client for your app
You want to automate the process of making the settings changes.
To make custom settings:
Use AppSettings.
First, add a reference to System.Configuration assembly.
In your app.config file:
<configuration>
<appSettings>
<add key="ClientID" value="123" />
<add key="ApiUrl" value="http://somesite/TestApp/api.php" />
</appSettings>
</configuration>
In your code, to read the settings:
using System;
using System.Configuration;
class Program
{
private static int clientID;
private static string apiUrl;
static void Main(string[] args)
{
// Try to get clientID - example that this is a required field
if (!int.TryParse( ConfigurationManager.AppSettings["ClientID"], out clientID))
throw new Exception("ClientID in appSettings missing or not an number");
// Get apiUrl - example that this isn't a required field; you can
// add string.IsNullOrEmpty() checking as needed
apiUrl = ConfigurationManager.AppSettings["apiUrl"];
Console.WriteLine(clientID);
Console.WriteLine(apiUrl);
Console.ReadKey();
}
}
More about AppSettings on MSDN
To automate the creation of settings:
This all depends on how complex you want to get.
When you build your project, your app.config file becomes TestApp.exe.config
You can use ConfigurationManager class to write Config files.
Further, you can write a little Exe that writes the config file with custom settings and execute it as part of a build action. Lots of ways to accomplish automation which depend on how you intend to deploy your application.
A quick example of writing an app.config file appSettings section programmatically:
public static void CreateOtherAppSettings()
{
Configuration config =
ConfigurationManager.OpenExeConfiguration("OtherApp.config");
config.AppSettings.Settings.Add("ClientID", "456");
config.AppSettings.Settings.Add("ApiUrl", "http://some.other.api/url");
config.Save(ConfigurationSaveMode.Modified);
}

Override dll config

i have a class library, with domain objects (linq based objects, in .net
4.0).
i want to have this library use connection strings for its own app.config.
there are some problems:
following the model used by Settings : ApplicationSettingsBase, i created a
wrapper that should read the settings from app.config.
however, unlike the model, i provide default values.
the problem is that the properties which should load the data from app.config
internal sealed class ApplicationSettings : ApplicationSettingsBase
{
// other properties
[SpecialSetting( SpecialSetting.ConnectionString )]
[global::System.Configuration.DefaultSettingValueAttribute("Server=.;Database=RFPLUSSTD;User Id=SYSADM;Password=SYSADM;")]
public string MainConnectionString
{
get { return (string)this["MainConnectionString"]; }
}
// other properties
}
in app.config:
<connectionStrings>
<add name="MainConnectionString"
connectionString="..."
providerName="System.Data.SqlClient" />
</connectionStrings>
now, this doesn't work...
i tried to set the name of the conn string to the fully qualified name like
namespace.class.property, but to avail.
i don't want to use the default Settings class, used by the dbml because
it compiles the settings :D and i can't change them without recompiling...
i'm already using a different model of app settings class in a project in
1.1, but i thought 3.5 has grown enough and have its own objects, that
work..
So, why is not working and how can i make it work?
Thank you
You need to make sure that you have permissions in the file system to make the change. I hope you have considered that. If you are sure that you changed the config file and if it only brings the default settings, it might be loading the config file from output bin folder not in the project root. If you are sure that the modification fails, please post the error message.
Updated:
Hi Jack, I think the main issue with your code is that it is creating new instance of the ApplicationSettings class every time and if the setting is in user scope, you will be having null value and then it results to default value every time.
You could easily do it with the built in Settings class. By default the Settings can only be accessed within the Assembly, internal sealed partial class Settings (in Settings.Designer.cs). If you change this to public sealed you will be able to access the Settings from any assembly and the next thing is you have to keep the setting to Application Scope not User scope. Once you have done these two, you can retrieve and save without any problem.

Categories

Resources