views:

459

answers:

4

I have a WinForms application ("WF"), and a Library called by that WinForms application ("LIB")

WF has a Settings.settings (Visual Studio Designer) and app.config combo. I gather than the designer is a front end that auto generates the app.config file. To use those settings from within WF, I use the strongly typed properties of the class it autogenerates (i.e. WF.Settings.MyTimeOutSetting).

When WF calls a method in LIB, I want to use one of WF's settings from within lib. How can I retrieve a setting from the caller's (WF's) app.config while in the callee's (LIB's) code?

A: 

The same way you would in the windows forms. It will atomically look in the app.config of the calling app first

Cody C
LIB does not reference WF. So it has no knowledge of the auto-generated WF.Settings class.
frou
you may need to add an app.config file to your bizlayer for compile / intellisense purposes but it will not use it at runtime. You do the same for things like SubSonic or EntityFramework
Cody C
Here is another link to a similar question but it may not be exactly what you need http://stackoverflow.com/questions/685259/getting-configuration-settings-from-web-config-app-config-using-class-library
Cody C
+1  A: 

Add a reference to System.Configuration to your proejct.

Then in the particular .cs or .vb (or whatever) file you are wishing to make a reference to the config file add the following:

C#: using System.Configuration; VB: Imports System.Configuration

then you can access the web config by using something like this:

C#: System.Configuration.COnfigurationManager.AppSettings["THE_SETTING_U_WANT"] ;

VB: System.Configuration.COnfigurationManager.AppSettings("THE_SETTING_U_WANT")

IF you want a full section I think there are methods in that class to do that as well.

bbqchickenrobot
That seems like it should work, but AppSettings has Count=0 and the indexer returns null
frou
This always works very well for me... but it depends on what info you're trying to retrieve. what settings are you trying to retrieve from your app.config? if it's in the <appsettings /> section the above wouldn't work. You can also use GetSection() or you could move the info you wish to retrieve into the <appsettings /> section assuming it fits the key/value paradigm.i.e. - <add key="Name" value="MyAppName" />Also, if you're attempting to retrieve a connection string you might try: ConfigurationManager.ConnectionStrings["NameOfConnStirng"];
bbqchickenrobot
This may help you out a bit:http://msdn.microsoft.com/en-us/library/system.configuration.configurationmanager_members.aspx
bbqchickenrobot
"if it's in the <appsettings /> section the above wouldn't work"should read - "would work"
bbqchickenrobot
It is in "<applicationSettings>" - I will look in to that class. Thanks.
frou
+3  A: 

The answer is: don't do it.

Have the calling application either pass you whatever you need to know in the call, or perhaps in your constructor. The called component should not require knowledge of the caller.

John Saunders
It's not required - it's just useful. I bet there is a recognised way to do it.
frou
The recognized way is to not do it. Separation of concerns, component-based development; these things imply that the caller should supply the callee with what it needs. That way, it can be called in a different context.
John Saunders
As far as I'm aware, the app in app.config stands for AppDomain, and they are in the same AppDomain. As I said, the setting is not needed, it ise just useful to use as a hint.
frou
I guess I'm not being clear. I mean that if the setting belongs to the caller, then the caller should pass it to you. The library should know nothing at all about the caller, or what settings the caller is using. This permits a different caller to call the same library, with totally different settings, or a different settings mechanism entirely.
John Saunders
Well right before caller passes info, he should still be able to use this information. Also, just because you think seperation of concerns is the best way, it may not be. If this is a beginners project or a quick and dirty program seperation of concerns doesn't really concern (NPI) the OP.
bbqchickenrobot
I alredy know the point you're stressing, so it isn't helpful. I'm almost certain that there is a recognised mechanism associated with reading the "topmost" applications app.config, like bbqchickenrobot points out.
frou
All sorts of dumb hacks are possible, they're just not wise. If the "library" is really a "library", and wants to be used by different callers, then it cannot depend on detailed knowledge of the caller. If you want it to depend on the caller, then it's part of the caller, and perhaps shouldn't be a separate library. It's not about a buzzword, it's about reuse. Will you ever use the "library" with a different caller? Will you require the different caller to have the same configuration setting?
John Saunders
Alright - it's a "Class Library" (Visual Studio terminology) that will not be reused.
frou
If it will never be reused, and never maintained by anyone else, then go ahead and hack. I'd still call it a bad example, and possibly a bad habit.
John Saunders
Thanks for your blessing, but this thread of conversation hasn't helped at all. I asked how to do something specific, not whether it was a good idea. I already knew the tradeoff.
frou
You're welcome. Sorry I was unable to distinguish between you, who knew what you were doing, though it's what we would normally consider the wrong thing to do, and many others who come here for answers, post a question just about like yours, and who actually do _not_ know that what they're asking for is far from a best practice. In the future, if you don't want to look like you're inexperienced, you can say things like, "I know this is normally a bad idea, this is not a normal situation, and I'm doing it anyway". But nicer.
John Saunders
+1  A: 

Like John said, this is a bad idea. The caller (exe in this case) should pass the needed information to the DLL. That way you can re-use the DLL later, somewhere else, and not have some 'invisible' dependency on an app.config setting.

That said, it irritates me when people just tell you what not to do and never answer the question.

Try this:

Dim oConfiguration As System.Configuration.Configuration
oConfiguration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None)
Dim sValue As String = oConfiguration.AppSettings.Settings("setting").Value
MattH
Yes, that is iritating to me too!
bbqchickenrobot
I didn't answer because I didn't think it would take long for him to find the wrong way to do it. I answered six minutes after the question, at which time he might still have thought this was a good idea. Now that he's decided he doesn't care about reuse, there's no reason for him not to know how to do it.
John Saunders
Guys, would you rather immediately answer with something that will cause trouble further down the line, or to make sure the questioner knows what he's asking? He gave no indication that he would never call this code from a different caller, and used the term "library", which implies reuse. This answer answers his question, yet restricts reuse. Also, others will be reading this, and I want to make sure they know why not.
John Saunders
He's now said it will never be reused. In that case, I'd have no no problem showing him how to do it. I would have questioned why have a separate assembly, but then it might be that the caller was a web site, which would answer that question.
John Saunders