I have two independent projects in my Visual Studio 2008 solution. Both has its own App.config. But in one project, I need one or two properties defined in another project's App.config. Is it possible to share part of the App.config contents from other project?
Yes - of course. Any configuration section can be "externalized" - e.g.:
<appSettings configSource="AppSettings.DEV.config" />
<connectionStrings configSource="MyConnection.config" />
or
<system.net>
<mailSettings>
<smtp configSource="smtp.TEST.config" />
vs.
<system.net>
<mailSettings>
<smtp configSource="smtp.PROD.config" />
Any configuration section can be put into a separate file that can be shared between projects - but no configuration section groups, and unfortunately, it's sometimes a bit tricky to know which is which.
Also, in some cases, Visual Studio will complain (using red wavy underlines) that the "configSource" supposedly isn't valid - but it is - it's defined on the ConfigurationSection object in the .NET config system.
UPDATE:
another feature that hardly enough developers seem to know and use is the ability in Visual Studio to add existing files from a different project as a link:
With this, you can add links to files into your local project, and they'll always be kept up to date. Great productivity booster if you need to do some file-level sharing (like for common configuration files or such)!
Try this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings file="PROD.config">
<add key="common.Currency" value="GBP" />
</appSettings>
</configuration>
Only the "running" app.config is used, but you can go external like marc_s says.
You can also create a .Settings file that's "shared". Go to the "shared" project properties, the Settings tab on the left, create a setting with Application scope, and set the Access Modifier on top to Public. In your other project you can then use ClassLibrary1.Properties.Settings.Default.SettingName to access it. It will be strongly typed, but you may need it at compile time.
Something I like to do, especially when trying to coordinate ServiceModel elements between libraries and tests is to use configSource to fragment the config in the target library and simply link/copy always the fragments in my test projects.
That way I only maintain in one location.
You could take it one step farther and simply have a common directory in the solution and link the fragments in all projects.
In that situation, I would think using a Database to store some configuration data would be ideal. Each app does its own thing, but they look to a shared database to get those common pieces of information.
EDIT: I spoke too soon! Looks like both the OP and I learned something about config files =D
Related
I have implemented a dll for consuming an API. It's working properlyn but now I have to allow user to consume the dev and production API's (we have separate environments for dev and production). I donĀ“t know how to do it.
I can implement a switch and allow the user to set production or dev and just change the path, but I'm guessing this is bad practice.
Actually, I have a path stored in app.config. Any suggestions on how to implement this or is the only way to send the user two dll's, one for production and one for dev?
The correct way to do this would be:
to store the path in app.config
create environment specific transforms for the config file
transform the config file during deployments
Sample config:
<add key="apiUrl" value="http://localhost/myapi" />
And corresponding transform file
<add key="apiUrl" value="http://devhost/myapi" xdt:Transform="Replace" xdt:Locator="Match(key)" />
You can use plugins like SlowCheetah to do the transformation.
Alternatively, you can use MSBuild tasks to do the transformation as well:
<UsingTask TaskName="TransformXml"
AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll"/>
<Target Name="TransformWebConfig">
<TransformXml Source="C:\myapp\app.config"
Transform="C:\myapp\app.dev.config"
Destination="C:\myapp\bin\<web.config or in case of exe, product.exe.config>"
StackTrace="true" />
</Target>
Note: DLL files in .Net cannot have config files. So I'm assuming you're referring to the exe or web.config of your product.
Conditional compilation could be an option for this.
It's not too hard to set up. A good article is:
http://www.codeproject.com/Articles/451734/Visual-Studio-Use-Conditional-Compilation-to-Contr
I have a windows console application. I get some values from app.config. There are for writing log files. When debug, I want to write them on my desktop. But when publish the application, the logs should be in the remote server. Now I have to manually set the values each time between debugging and publish.
Can we create two version app.config files and use them properly?
When check in, we only check in the app.config for production.
Please remember, it is not an asp.net web application. In that case, we can have different web.config files.
Yes you can, but you need an extension to do it. I have used SlowCheetah for this in the past.
Use SlowCheetah to add a transform for your release build that changes the log-path. Your app.Release.config transform file could look something like this.
<?xml version="1.0" encoding="utf-8" ?>
<!-- For more information on using transformations
see the web.comfig examples at http://go.microsoft.com/fwlink/?LinkId=214134. -->
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<appSettings>
<add key="logDirectory" value="D:\releaseLogs" xdt:Transform="Replace" xdt:Locator="Match(key)"/>
</appSettings>
</configuration>
You can add a transform for Test and Debug environments as needed.
In your source control you would check in:
An app.config that contains all the keys your application needs
An app.Release.config that contains transforms that changes the keys that need to be different in your Release environment.
When your solution is built, SlowCheetah will apply the correct transforms to your app.config based on the target environment.
Another alternative to extensions is to simply add a Post-Build event in your project:
if "Debug"=="$(ConfigurationName)" goto :nocopy
del "$(TargetPath).config"
copy "$(ProjectDir)\App.Release.config" "$(TargetPath).config"
:nocopy
Copy your App.config to App.Release.config and change as needed, when you publish as Release the appropriate file will be used.
I am creating a windows service in .Net 4.0 and testing some functions of said service with a windows forms client by referencing the service project.
The service project has an App.config file and that file looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<clear />
<add name="myLocalMySQLDBUsername" connectionString="username"/>
</connectionStrings>
</configuration>
When a function belonging to the service calls:
ConfigurationManager.ConnectionStrings("myLocalMySQLDBUsername").ConnectionString
a null reference error is thrown because my connection string is not loaded. The only connectionStrings that are loaded are from the machine.config file located in c:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\Config\machine.config
If I create an application scope setting for the service, I can get that setting by using the My.Settings.setting -> so it's not like the App.config file is not being read.
My question is: why are my connectionStrings not being loaded from the App.config file?
Thank you for your help.
UPDATE:
Also, at this point, even a work around would be appreciated; the only reason for using app.config is to be able to encrypt the contents using the DpapiProtectedConfigurationProvider (the contents will have some username/password values for service and database connections).
I tried creating an AppSettings section manually in the app.config but those settings were also not read by the configurationManager (count = 0).
UPDATE 2:
Per a suggestion, I tried to manually open the app.config file like so:
Dim exePath As String = System.IO.Path.Combine(Environment.CurrentDirectory, "ServiceName.exe")
Dim myConfig As Configuration = ConfigurationManager.OpenExeConfiguration(exePath)
So here is the weird part, when I look inside, path is correct (points to my app.config) but the connectionStrings are still being loaded from the machine.config file (my connectionStrings are not loaded)!! ARGH
UPDATE 3:
Okay, so, I figured it out. When referencing a project(parent) from another project(child), the child's app.config is used even if the parent's classes are being used. Thus, I can get the connectionStrings to show up if I copy them over to the child's app.config. When trying to open it manually, my currentDirectory was of the child, not the parent (strange how it did not throw an exception - it wouldn't have been able to find the config file ... it just silently used the machine.config ... oh well).
Thanks all for the help!
The first thing you'll want to do is make sure that the service account has access to the file (if not running as SYSTEM). It sounds like it should be ok though since you mention My.Settings.Setting works.
The other thing to look out for is to make sure that the app.config has the name of the service executable in it - so if the service exe is MyService.exe the app.config must be named MyService.exe.config.
The last thing to make note of: libraries will read from the executable's app.config that loads the library, not the app.config that is with the library. So if you have a project for the service executable MyService and a project for the library MyServiceLibrary the code in the library will read the app.config from MyService not MyServiceLibrary.
I saw some people say this problem might be fixed by manually re-adding a reference to System.Configuration.dll
SIDE NOTE: If that really is you whole app.config file and not just a snippet then that is your problem... you're app.config file should be MUCH more complicated or .NET will not be able to load it.
WORK AROUND: Use the configuration manager to open this config file (there is an API for that.) You can't get it to load auto-magically just tell the config manager to open it.
I still think the problem is your config file is invalid -- could you please post the FULL file?
Make sure the config file is deployed to the same folder as the executable file, and that it's called your.assembly.exe.config.
I had a similar problem, but in my case it was because I had changed the project's namespace. This is also used as the application settings section element name in the config file, so the code was not finding the new section name. Fiddling with one of the custom setting's values in the project properties and rebuilding caused the new section to written into the app.config alongside the old ones which was what indicated the issue to me.
I was recently given a heap of programs to maintain and I am trying to find some help in adopting some best practices. They are essentially three independant softwares which use a common DLL to manage a series of settings the apps all share. The DLL works this way: it swaps the user settings file (XML file buried deep in the user's configurations folder in Windows), with a fix file, specified by a hardcoded (egad!) path.
The rationale behind keeping it as user settings and not app settings is that the DLL can be found in several locations (one for each app that will use it), and so the user settings file is common (if all copies of the DLL are the same compile), whereas by using application settings there would be as many app.config files as there are copies of the DLL.
I'm trying to conceive of a better way to centralise these configurations and end the senseless file swapping. One approach (actually, most likely the best approach) would be to redesign all 3 apps so they all use a central dll with its own "app.config". Are there other more recommendable venues?
Have you considered using the Windows Registry? We all hate it, but maybe it's the best option in this case as it is centralized and you could share settings easily across applications.
EDIT: If you don't like the Registry (and I don't blame you for it), you can create an XML or some other configuration file in a directory under the Application Data special folder. This is how this is done these days as far as I know.
string appData = Environment.GetFolderPath(
Environment.SpecialFolder.LocalApplicationData));
string folder = "MyApplicationName";
string fileName = "settings.xml";
string path = Path.Combine(Path.Combine(appData, folder), fileName);
For this precise problem, if it's a .Net DLL, you could use the GAC, this would centralise your DLL. All software would know where they could access this DLL. And in this way, you could have less refactoring to do.
This is only a patch for this problem only. I would not recommend this, for new developpement.
GAC in Wikipedia
You can use settings in a common file - most likely stored under AppData in the users settings folder
The advantage here is that you do not have to modify any code whatsoever.
The application would store its settings in its normal config file and refer to the common file for the dll settings:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings file="commondll.config">
<add key="KeyToOverride" value="Original" />
<add key="KeyToNotOverride" value="Standard" />
</appSettings>
</configuration>
Then in the common file commondll.config:
<appSettings>
<add key="KeyToOverride" value="Overridden" />
<add key="KeyToBeAdded" value="EntirelyNew" />
</appSettings>
Perhaps this solution that shares configuration settings between an ASP.NET app and Console app will contain useful information.
I have a solution in Visual Studio 2008 which contains multiple C# projects. Each project has it's own config file (App.config and Settings.settings). This makes sense architecturally as each module is autonomous and is used in a number of different solutions.
My problem is that when I compile the solution only the config file for the startup project (or project containing the executable) is included. For other modules the config settings are compiled into the DLL. So my question is, is there any way in Visual Studio of combining multiple config files, or linking them so that settings for DLLs can be changed at runtime?
I'm not sure if this is what you are looking for or if it will help but just as a lead into an area to explore, note that you can link two Config files. For example, I have my connection string in a separate file so my connectionStrings line in Web.config reads:
<connectionStrings configSource="WebCS.config"/>
Then, in the separate file, I have:
<connectionStrings>
<add name="BSDIConnString"
connectionString="Data Source=XXX;Initial Catalog=XXX;User ID=XXX;Password=XXX"
providerName="System.Data.SqlClient"/>
</connectionStrings>
I don't believe there is. But just in case you're unaware.
OK good people, all you will ever need to know about VS config files:
Link
After more digging, I found this quite useful post
http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/2710647c-6414-42c4-90b7-fd7603f55ae0/
Just in case anyone runs into the same issue, the above seems to be the most practical way of getting around it. Although beware that with this solution creating setup packages may become tedious:
http://bytes.com/groups/net-c/498720-app-config-dll-not-getting-added-setup-project