I am reading articles, forum posts about applicationSettings for almost a week now.
In almost every thread there is someone that appears to have correctly pointed out that when deployed, class libraries cannot have config files as executables do. I mean you can always have the file there ClassLibrary.dll.config, but it won’t make any difference if you just copied it from the output folder of the class library project into the folder where the application was deployed.
The application’s code will not be able to read any settings from that file (unless some modification are made to both the exe and the dll’s config files).
The same people say, that to use those settings that you happen to have created at design time for the class library, you have to merge somehow its applicationSettings group section into the deployed application.exe.config configuration file of the application that host/consumes the dll. I have yet to see a clear example of how to do it.
However, you can access the class library’s settings you had configured at the last compilation without merging its applicationSettings group section into the executable’s config file. All the settings created in the class library during design exist as properties of the Settings class from the My namespace. Because they are decorated with a[DefaultValueAttribute] these properties will always return a default value even though there is no setting present in the configuration file. If a setting existed, that specifies other value it will override the default one.
So, in other words, you can merge the dll’s settings into the exe’s config file, but you don’t need to, unless you want to provide the user with a way to override the default values – the ones that are specified using the [DefaultValueAttribute] hard coded in the assembly.
Now, you listening to me as I keep talking about the merging of the class library’s applicationSettings group section.
How is that done exactly?.
Where do I copy the settings?
Do I just grab the setting elements and stick them in the exe’s configuration file in the applicationSettings group section?
I could not find a practical example on any forum and I just assumed that this is how it should be done. While developing my solution was not that obvious that I am wrong. The truth came out only when I deployed my application at the client. The application instead of using the newly configured values was constantly defaulting back to the setting values I specified during design at the last compilation.
So, let’s say that I want to provide the user with a configuration file, where he could change setting values and they actually stick. I couldn’t find anything specific on MSDN so anybody who knows any material, please let me know. What I am presenting you in the next lines I discovered by trial and error.
Anyway, let us use a very simple, practical example. Let’s use VB.NET
1. Create a Class Library project called ClassLibrary.
2. Click on the Solution Explorer’s toolbar on Showing all files button
3. Expand MyProject and double click Settings.settings.
4. Add a setting called Message, application scoped whose value is “Hello!”.
5. Create a property in Class1.vb (the automatically added class)
6. Create a VB WinForms project and call it WinForm.
7. Add a reference to the ClassLibrary project.
8. Add a button to the already created Form1 and double click on it.
9. Add the some code to the the Button1_Click handler. Should look like this.
10. Have the WinForm project “Set as Startup project”
Now, while in the IDE everything works beautifully. Run the solution and you’ll get the expected Hello! when you press the button. If you go and change the setting in the app.config of the library to say “Good bye!” and you run the solution again you get a “Good bye!”
However, what we want to do is to simulate a run outside the development environment.
1. Right click on the WinForm project and chose “Open in Explorer”.
2. Get to the Debug folder. Note that there’s no WinForm.exe.config file yet. Let’s create one quickly.
3. Switch back to VS and while the WinForm project is selected click to Show All Files.
4. Expand MyProject, open Settings.settings, create a setting “A” with value “A”(doesn’t matter what) and save.
There we go, an App.config was created and if I build this solution, the Debug folder will copy it to a WinForm.exe.config.
So far we have two configuration files in the output folders of each project:
into the WinForm’s config
The question is what and how do we merge the ClassLibrary.dll.config into WinForm.exe.config? If we use the Settings designer that we can invoke by double clicking the Settings.settings file and add the Message setting into the WinForm.exe.config it will not work. Not even when ran from the IDE.
The message box will display the default value of the Message property – the one persisted in the ClassLibrary assembly.
However, if we modify the Winform project’s app.config, by basically copying the section definition and then the whole section itself from the app.config of the ClassLibrary project to their corresponding places in the WinForm project’s app.config, and then compile we obtain a Winform.exe.config that must look like this.
Notice that as we did not have any relevant settings in the WinForm project itself we got rid of the section definition and the settings we added previously.
An unfortunate thing is that the Settings designer when invoked again will pick up this setting and import it but it will save it back to the app.config in the <WinForm.My.MySettings> section if you answer yes to save the app.config changes when asked. This won’t harm unless there’s somehow code in the WinForm assembly that uses a property in My.Settings called Message. If it does annoy you, you’ll have to manually delete it and refrain from saving changes that the Settings designer might want to apply to app.config.
If for various reasons you want to keep the configuration in two separate file – maybe you grew fond of the ClassLibrary.dll.config name – you can modify the WinForm project’s app.config to look like:
and copy the ClassLibrary.dll.config from the output folder of the ClassLibrary project to the output folder of the WinForm project after you removed some parts and it looks like this.