When you create a Settings config file, it creates a Settings class that is marked internal to the Properties file. For example, the generated code from one I just created looks like:
namespace ExportImportManager.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = new Settings(); public static Settings Default { get { return defaultInstance; } } |
The problem with this is how can I access these settings from another project I can't overwrite this file and remove the internal modifier since this code is autogenerated every time you add a new setting using the IDE.
Does anyone have other suggestions on how to use 2.0 Settings from another project within your application

Is this a bug or by design? Settings declared internal when autogenerated???
virayanna
You then end up with a blank App.config as
< xml version="1.0" encoding="utf-8" >
<configuration>
</configuration>
So for a test I added a property using the ide Settings ...
<applicationSettings>
<SettingsStuff.Properties.Settings>
<setting name="SettingFromIDE" serializeAs="String">
<value>ide setting</value>
</setting>
</applicationSettings>
Now at this point I also have my custom settings class which looks like...
namespace SettingsStuff
{
public class TestAppSettings : System.Configuration.ApplicationSettingsBase
{
private static TestAppSettings myPublicSettings = new TestAppSettings();
public static TestAppSettings Default { get { return myPublicSettings; } }
[System.Configuration.ApplicationScopedSetting(),
System.Configuration.DefaultSettingValue("Default1")]
public string MyPublicSetting1
{
get
{
return (String)this["MyPublicSetting1"];
}
}
I then decided to make sure this "MyPublicSetting1" is in app.config so I decided to add it with the designer and it did as I expected (and hoped)...
<applicationSettings>
<SettingsStuff.Properties.Settings>
<setting name="SettingFromIDE" serializeAs="String">
<value>ide setting</value>
</setting>
<setting name="MyPublicSetting1" serializeAs="String">
<value>public setting from my custom classs</value>
</setting>
</SettingsStuff.Properties.Settings>
</applicationSettings>
I then can access "MyPulicSetting1" by using my custom class outside of the project as...
SettingsStuff.TestAppSettings.Default.MyPublicSetting1
Is that they way I should be handling this
The part I sort of don't like is from within the main settings project I of course could access it as
SettingsStuff.Properties.Settings.Default.MyPublicSetting1
I guess it's not too big of a deal, but it would be nice to enforce throughout the whole application just one entry point (using my custom TestAppSettings class).
Am I close:)
Foxcare
Yes, if you want to use the same setting in multiple projects, and you want to use the settings designer, you will have to create the same setting in multiple projects.
The settings designer was primarily intended to provide an easy and approachable way for assemblies to store their private data (i.e. window locations, MRU lists and such). It also provides other designers in the visual studio IDE a way to store settings (i.e. the windows forms designer can bind properties to settings). This all works on top of the .settings files. A custom tool is then run that generates code from the contents of the .settings file.
The actual code that is being generated utilizes the new public client configuration API. Our intention was that if you wanted something that the settings designer couldn't provide, you would write code using this API directly. I have included a little code snippet below to show what you'd need to do in order to use this API (nothing magic here).
public class MyPublicSettings : System.Configuration.ApplicationSettingsBase
{
private static MyPublicSettings myPublicSettings = new MyPublicSettings();
public static MyPublicSettings Default { get { return myPublicSettings; } }
[System.Configuration.
ApplicationScopedSetting(),System.Configuration.DefaultSettingValue("Default1")]
public string MyPublicSetting1 { get { return (String)this["MyPublicSetting1"]; } }
[System.Configuration.
ApplicationScopedSetting(),System.Configuration.DefaultSettingValue("OtherDefault")]
public string MyOtherPublicSetting { get { return (String)this["MyOtherPublicSetting"]; } }
}
(Strictly speaking, the shared field/default property accessor are not something that is part of the API, but rather a convenient way to get hold of a common instance of the settings class...)
The client configuration API is very powerful compared to the old appSettings section/dynamic properties, and provides features such as a pluggable provider support that allows you to use other means than the app/user.config files to store your settings, read/write settings per user, roaming settings, upgrade of settings between application versions. The list goes on.
If it is not too late, I would suggest that you'd look into using the client configuration support instead of using your own xml readers. If you look at the class above, it is not exactly rocket science, and it will give you a whole lot of things for free.
A good starting point if you want to read up on the client config API would be this:
http://msdn2.microsoft.com/en-us/library/k4s6c3a0.aspx
Best regards,
Johan Stenberg
ImagineNation
I'll try to explain....
You said you should create the config file using Project-- add file--- application configuration file and keep it as "App.config." You could then either a) make settings for it using the Settings designer or b) manually add the settings into the config file. In either case, you then have to add the proper accessors to those properties in your custom AppSettings class.
What seems Soooo goofy though is that this AppSettings class is practically IDENTICAL to the one that the Settings designer will make (Settings.Designer.cs) . Of course it won't be identical if you don't use the Settings designer to add settings to the project, but I almost think that you should work with the Settings designer, because there is no way to really enforce that someone working in the project won't use this option and thus potentially over-write you App.config.
I guess what I'm trying to get a handle on is that both the Settings designer in the IDE and the stuff you manually want to add to your custom class will BOTH be using the same App.config file. So I'm still sort of wondering if it's better to just not even bother creating your own custom classes and instead just modify the default Settings class from:
internal sealed partial class Settings to public class Settings
If I do that then everything is a lot less error prone.. when a setting is added using the designer you're done. I don't mind doing things the long-way (actually I prefer to hand code stuff), but I don't like that someone could then come in and add a property using the Settings designer and it alters the same file that you are working from for your custom class(es) (the App.config)
I'll look over the documenation more but it's really difficult figuring out how this interaction between the ide settings and custom settings classes is supposed to work out.
Ddscool
Best regards,
Johan Stenberg
Ryan Bolger
It sounds like you are saying I'm still going to have to declare each property in the Settings of each project even if they are the same property that I'm setting up over and over again In other words I'm going to have to declare "TheSettingIWantToShare" in the Settings options in every project that needs to use that That seems like a lot of work... which I find odd since in 1.1 I could use the ConfigurationManager to pull out the app.config settings from the main project without much problem. It seems like this becomes more difficult in 2.0 does it not
It sure seems a lot easier to just delcare the Settings class in the main file you want to share as public (vs keeping it internal) and viola you have access to those settings from anywhere within the application using the MainNamemspace.Properties.Settings.Default.SharedItem approach.
I know this isn't the most secure thing, but it sure seems to beat having to add each property in the settings for each project (but then again, I could toally be miscontruing what you're saying:)
Thanks so much for all your time with this. It's been driving me nuts for days, and I've been googling like crazy:)
Dehim
I've been 'trying' to follow a lot of the info from that link you provided http://msdn2.microsoft.com/en-us/library/k4s6c3a0.aspx and I have to admit, a lot of is still pretty unclear, but I'm working on it.
I created a myappname.exe.config file and then created the class you described above, and it worked fine in regard to loading the settings - Thanks! I also added a UserScopedSetting and when I called save on the properties it worked great saving the setting to a user.config file.
Just a few other questions if you get a chance that are probably in the docs somwhere but I couldn't find them....
1) What if you wanted to use different config names What if I wanted to load a "myapppropertiesconfig" for my application scoped config instead of creating a 'myappname.exe.config' (same thing with user.config.. see rationale in next question.)
2) If I create my own Settings class (as you discribed) and then someone goes and tries to make their own settings class using the IDE settings designer, what should happen In my litt test, it appears that the app config I created manually to be used with "MyPublicSettings" class got completely wiped out! This could be very dangerous so I'm assuming (back to question 1) that I should some how use a different name to stort my app.config settings and my user.config settings - considering that both will get wiped out if someone descides to use the ide to create some settings
fg_garda
Sorry if I wasn't clear; you will still not get access to the settings class in the other project, but by using the SettingsGroupName attribute, you can have two different settings classes defined in two different assemblies that both access the same value in the .config file.
If you have a settings class in your main executable with a string settings named TheSettingIWantToShare
namespace TheDefaultNamespace.Properties {
internal class Settings {
[global::System.Configuration.ApplicationScopedSettingAttribute()]
public string TheSettingIWantToShare { }
}
}
you can put a settings class that looks something like this:
[SettingsGroupName("TheDefaultNamespace.Properties.Settings")]
internal class Settings {
[global::System.Configuration.ApplicationScopedSettingAttribute()]
public string TheSettingIWantToShare { }
}
in a dll assembly that you reference from the main application. Since I didn't put a SettingsGroupName attribute on the Settings class in the main executable, it will read its values from the TheDefaultNamespace.Properties.Settings section of the running application's .config files.
Since I *did* put a SettingsGroupName attribute on the settings class defined in the dll, it will use that to locate the section in the running application's .config files... So, you will have two instances of two different types, one in your main .exe and one in your .dll, but both will get their values from the same location in the .config files...
And, yes, you will have problems running the beta2 version of VS2005...
Best regards,
Johan Stenberg
Drew Marsh
Ok, I'm 'almost' there I 'think.' When you say the group name is "WhateverNamespaceTheSettingsLiveIn.Properties"
My Settings namespace in this example is:
namespace TestingSettings.Properties {...
So I tried defining the attribute:
[global::System.Configuration.SettingsGroupName("TestingSettings.Properties")]
The question I know have is, how do I access these properties from my other project (reference to project is added)
I still do not have access to the Settings object when I try:
TestingSettings.Properties.Settings.
(complains Settings protected. I know an easy way around this would be to just declare the Setting public, but I'm guessing that's not the correct thing to do.)
Is the problem that I'm using vs 2005 beta 2 (since I noticed from your thread there is a bug beta 2 ) or am I simply trying to access the settings incorrectly from my other project
Thanks again Johan, I feel like I'm almost there. I really don't want to have to write my own custom class that serializes xml to an object, so I'd love to have this working.
VBRocksLikeMad
But I'm lost:(
You mention in the article
I'm not really sure exactly what you are saying above. Is there a concrete example showing this in use somewhere
Am I supposed to add an attribute [global::System.Configuration.SettingsGroupName("MyApp.Settings")] Somewhere in my Settings.Designer.cs class
Thanks again for trying to help.
You also mentioned in that article that you would question the use of needing to have access to settings from different projects. I'm wondering if our team is doing things wrong ... we have a few projects that together form our final assembly. We only want one user.config and one app.config for the project. Isn't it normal to want to have access to these files from anywhere within the application
delly_jm
szabti
If you start sharing the same settings between multiple assemblies, you add implicit dependencies between them, which makes maintaining your system very difficult. I much prefer having an explicit API where I can pass the value of the settings that I want to share. In essence, sharing settings is equivalent to using global variables, which is also something I try to avoid...
As you probably have noticed, if you put it in the automatically generated file (settings.designer.cs), it will be blown away whenever you make any changes in the settings designer, just as the warning at the top of the file indicates...
If you really need to share settings, I would recommend adding the group name attribute on the type declaration on the user part of the partial class.
To create/navigate to the user part of the file, open the settings designer and press the "View code" button. The file name would most likely be Settings.cs (assuming that you are using the default settings file) and after adding the attribute as indicated in bold it would look roughly something like this:
// This class allows you to handle specific events on the settings class:
// The SettingChanging event is raised before a setting's value is changed.
// The PropertyChanged event is raised after a setting's value is changed.
// The SettingsLoaded event is raised after the setting values are loaded.
// The SettingsSaving event is raised before the setting values are saved.
[global::System.Configuration.SettingsGroupName("WhateverNamespaceTheSettingsLiveIn.Properties")]
internal sealed partial class Settings {
....
Regarding your questions about multiple app.config/user.config files; if you have multiple assemblies that define settings classes, in an executable, they will all share the same app.exe.config and user.config file(s). The name of the files depend on the application that is executing, not on the assembly name of the assembly where the settings class is defined (*).
Each settings class will read/write it's values in it's own sections within the file(s).
The name of the section in the .config file is based on:
1) The value of the SettingsGroupName attribute of the settings class (if any), which is what we rely on here in order to share the setting value between multiple settings classes/projects
2) If no SettingsGroupName attribute is present, the namespace qualified name of the settings class.
(*) This is almost true, and you have to do some fairly advanced stuff for it to not be true. For a more exhaustive explanation on how the file paths are computed, you can check out Raghavendra's Client Config FAQ. The main gotcha is that you can spin up additional app domains with different evidence, which will mean that depending on from which app domain you are getting the settings, you may get different values. Again, if this doesn't make sense to you, don't worry - like I said, it is a fairly advanced scenario that most mortals don't have to care about :)
Best regards,
Johan Stenberg
William Gates
2) I believe that you have made the all to common mistake of either manually adding the myappname.exe.config file in the bin folder or added it to your project. Visual Studio assumes that the configuration file name is app.config in the project. This file will be automatically renamed and copied to the bin folder as part of the build. See http://forums.microsoft.com/msdn/ShowPost.aspx PostID=107411.
Best regards,
Johan Stenberg
WantaBe
Just curious.. So close to having the issue resolved. Follow up on my last post would be great if you get a chance. Thanks.
In the meantime, I went ahead and am using my own xml file readers etc to do all of this. Would be nice to be able to use the settings the way they were intended though.
Jeremy613
The current options I'm debating about...
1) Simply change the delcaration of the main app Settings class from internal sealed to public.
2) Create my own public Settings class that extends ApplicationSettingsBase and use the ide to add---> new item---> app configuration file (creates App.config)
3) Create my own classes that serialize from xml files and are completely independent of the Settings of Visual Studio.