How can my commonLib.dll use the referencing applications app.config? - c#

Ok so i have 2 classes so far that i want to put in my common dll, logger and db. im moving them from my current project to a new class library project and changing their namespaces and whatnot. The issue I am having is that I wish to use the app config of my application (or any app that I want to reference my commonlib.dll) but I dont know how to use the referencing projects app.config. Is there any way to do this?

The OpenExeConfiguration() methods of ConfigurationManager are your ticket. One of them will take a path to the executable, allowing you to open the app config of a specified application (even a different one; you can use this technique to change the configuration of another application before launching it with Process.Start()). The other one will open the app.config of the current application (even if your library is used by multiple apps) for a specified user level (All users, current roaming user, and current roaming and local user). Usually, when dealing with an actual app.config, you want the one that applies to all users; the per-user configs are stored in each user's AppData folders.
Also, one last thing; unless your library has its own config file, the ConfigurationManager properties, like AppSettings, will be populated based on the current executable's app.config. So it could be as simple as using those properties. Keep in mind that those properties are read-only and only loaded once at program startup, so if you make changes to your config during program execution that you want to be effective immediately, it's better to explicitly load/save config files.

Related

What is the difference between appsettings.json and runtimeconfig.json?

What is purpose of either of that files?
When to use appsettings.json?
When to use runtimeconfig.json?
appsettings.json is for configuring your application. You (or your IDE) create this file. You manually maintain it with changes that you need.
runtimeconfig.json is an internal configuration for the .NET runtime, used when it needs to run your application. Generally, you don't touch, edit, maintain or even version control this file. It's created automatically when your application is built.
It's never an either/or situation: you generally use both. appsettings.json is used explicitly/manually, while runtimeconfig.json is generally used under the hood and very rarely used manually.
The appsettings. json file is an application configuration file used to store configuration settings such as database connections strings etc. This is basically a configuration file for configuring your application. You can able to edit it manually, whenever the changes are required.
The runtimeconfig. json file is generated automatically in the output directory when the application is built . It is basically a internal configuration for the .Net Runtime. There is no need of making any changes or any edit in this file manually as it is automatically generated at your application's Runtime.

Settings specific to a class

I have a class where I retrieve certain settings from a database (usernames and passwords). This database is sitting on a network, and it means that if the passwords are changed, I can simply change it in the database, and all the applications that use this class will still work.
I am fully aware of the pros and cons of storing usernames and passwords in a database and in a separate location. I don't want to discuss those, please.
The class has a hard-coded static string that is the path to the database. It is a fully qualified network name (not just the drive letter). I did this because we had an issue where our network DNS got screwed up, and drive letter mappings stopped working, and some people have different drive mappings anyway.
We recently had our server moved, so I now need to go through and change these hard-coded strings.
I was thinking that I should store the path in a settings / configuration file instead. I considered "application.settings", but it is not an application setting; its specific to the class. Is there a preferred way of doing this in the existing .Net framework (this is a C# issue)?
I could simply have a small text or XML file that sits in the application directory, which is probably fine... is there an existing framework namespace or open-source code snippet that someone knows of that I can use?
I think, if you want class specific configuration, you should try to have those class instances, configuration driven. Another way of thinking but; Defining a something in a configuration file, will create an instance of the defined classname.
For example: Create a section, and call it, <Modules> and create items in like: <module type="<namespace>.DBConvertor" param="username=root;passwd=whatever"> This type will be created at startup (you need some coding here). And it's even possible to create more than one instance simultaneously with it's specific configurations.
This kind of configuration is already implemented:
You might take a look at this: "How to: Create Custom Configuration Sections Using ConfigurationSection" https://msdn.microsoft.com/en-us/library/2tw134k3.aspx
And creating instances from typenames, use the Activator class.
Besides that, there are many module/plugin libraries, (like Managed Extensibility Framework (MEF) https://msdn.microsoft.com/en-us/library/dd460648(v=vs.110).aspx but could be a little over the top in this case).

.NET App.Config issues across multiple projects

I have a solution that contains two projects. One project is a Windows Service that contains a few classes for performing various functions. The other project is a Windows Form Application that is meant for doing various testing and performing task that the service accomplishes on demand. For instance, the service will do a few various task at a certain time interval, but if you wanted to perform one of those task before the time interval has elapsed, you could load the Windows Forms Application and execute one of the task immediately. The Windows Form Application (from here referred to as the tester) references the Windows Service (from here referred to as Service) project. When the Tester loads, it creates an instance of one of the classes from the Service. Whenever buttons are pressed to perform the task, it references that instance that was created and calls the various methods of the class. The Service has uses application settings for the configuration, and thus has an app.config. The configuration settings are accessed using [ProjectName].Properties.Settings.Default.[SettingName]. When the configuration settings for the tester are changed on its own app.config (or exe.config after release), the settings are refreshed without a problem. If the tester is closed, configuration is modified, and then reopened, the new settings will be populated. If the Reload method is called on the Settings, the configuration is refreshed without a problem. The Service performs in the same way. The configuration settings are can be updated without a problem.
The problem is that if configuration changes need to be made on the service, when the service methods are called from the tester, the configuration does not take the new settings. Whatever settings the project was built with will be used. I cannot get the tester to recognize that the app.config/exe.config for the service has changed, and the new configuration should be reloaded and used instead of whatever configuration was used when the project was built in visual studio. Perhaps it I am not educated enough about this topic, but it seems to me that the app.config is rolled up into the .exe file created by the Service whenever it is built.
I have tried encapsulating the Reload method for the Service and calling it, and it doesn't seem to make a difference.
I have an example project that performs as is described above on a very basic level. The ideal goal is to be able to modify the exe.config file or files on the fly and have both the Service and the Tester pick them up without any problems. If you would like to see exactly what I mean from a coding perspective, an example project can be found here: example solution
Any help would be greatly appreciated. Thanks you for your time.
Update
I have managed to find A solution to this, but I am still curious if there is a better way. By using an app.config that is shared between both projects and using the Configuration Manager instead of App Settings, everything works as it is expected to. I prefer to use App Settings if at all possible; however it will work to use a shared app.config and the Configuration Manager pointed at that app.config.
One option is having both programs load from the same configuration file:
http://msdn.microsoft.com/en-us/library/system.configuration.configurationmanager.openexeconfiguration.aspx
Found the solution. An app.config must be added to the solution as is described above in my update. Once linked like that, you can add a settings file to the project and add settings/configuration to the project and they will be added to the solutions settings file. This will move with the build and fix the problem I was having.

Application Wide Settings Available to All Projects

I have a Solution with 3 projects in, each project needs access to certain settings. I'm looking for a way to have these setting values available to any project from 1 distinct source. I cant use the .Config file as that is relevent to that particular project.
I could use the database but have been told this is not good practice (Without an reason)
Any ideas?
You could do this:
create a solution.config in your solution folder
in each project's app.config, add this to your <appSettings> node:
<appSettings file="solution.config">
....
</appSettings>
You would have to put symbolic links to your common solution.config in each project folder - but you could have one single physical file that you share amongst the projects.
The <appSettings> node is the only one that allows that sort of "cummulative" settings - those from the file specified in the file= will be added to your app settings, but potentially overwritten by anything you specify explicitly in your app.config.
On the other hand, yes, of course, you could use the database. We do that, too, in most of our projects, since we typically do have access to the database, but not to the file system in the client's server machines. I don't see why that should necessarily be a bad thing - we have settings for DEV, TEST and PROD in a table - so you have all your settings in one place - and we pick those settings we need when we need them. Works just fine - of course, some settings like the connection strings to the database cannot be stored there - but the bulk of our config info is. Again: I really don't see any reason why this should be a bad choice per se - so unless your source can back his/her statement up with some facts and reasons, I'd ignore it.
You can define configSource attribute in a defined configSection, to reference an external file from which to load your properties.
Here you can find an example:
Is there any way for an App.config file to reference another full config file? (.NET)
You can also use a DB of course, but that would probably involve developing some kind of configuration console, since it's not a good practice to manage config attributes directly into DB.
Otherwise you can create your config file (an xml, or yaml for example) and create your own shared config parser.
I create a class to hold system-wide settings using either a Singleton pattern, or a Global instance (whichever you preference is).
If another project is in the solution, it can see the class (when references are added).
This also decouples the presentation of the settings from the storage mechanism (database, config file, custom XML file, whatever), and if you design to the interface, it makes unit testing more flexible, too.
You could add an entry into each projects .config file that points to the global one. You would need to read that in three places though.
Another solution that springs to mind is to put your common settings into their own assembly with it's own .config file. You then include that assembly in each of your projects. The .config file is read in the assembly and you can read out those values you need.
What kinds of settings?
You can use the system wide machine.config and web.config files for settings that apply across an entire machine.
\Windows\Microsoft.NET\Framework[64]\[version]\config\machine.config
\Windows\Microsoft.NET\Framework[64]\[version]\config\web.config
You could use the registry if you have access to it. Then all you would need is a class to read them out (and possiblty one to put them in) and each project could use that class to read them.
The major downside though is that you would have to add the settings to each machines registry that you run your solution on.

Multiple Applications, Shared Settings: Use the registry or XML-based configuration?

My Scenario
I have a class library that is going to be called from multiple separate executable applications. This class library needs to know about an address of a database server (and many other configuration options, auth info, etc) to access. I have a configuration and administration application, separate from the class library, that also needs to know and set these configuration options.
My Question
Is it be common practice to store these user specific configuration options in the Windows registry, or is it preferred to use the typical 'App.config' XML approach for the class library and allow the configuration tool to change and modify it?
I am leaning toward the registry approach, but I know many people have opinions about not using it. What would you do?
The best practice is to use XML configuration files in the user's %appdata% directory.
There are a number of reasons for this:
Your application is most likely to be installed into Program Files. If the user hasn't granted (or been granted) administrative rights to your application's process, you won't be able to write to the file.
I've worked in partially trusted environments where registry access is just simply not an option. The client had completely disabled registry permissions to the .NET Runtime on that server.
Your user should always have access to their own %appdata% directory. Here's a sample:
string configFilePath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "myAppConfig.config";
ExeConfigurationFileMap map = new ExeConfigurationFileMap();
map.ExeConfigFilename = configFilePath;
Configuration cfg = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
cfg.AppSettings.Settings.Add("mySetting", "myValue!");
cfg.Save(ConfigurationSaveMode.Modified);
// to read the setting back
string mySetting = cfg.AppSettings.Settings["mySetting"].Value;
// at this point, mySetting = "myValue!"
Remember to add the System.Configuration v2.0.0.0 reference to your project! The default System.Configuration namespace does not have all of the required classes.
I prefer xml configs over registry settings because I can simply make a class and use the xmlSerializer to open and save right into my classes.
Check this topic out for a similar SO question.
In my specific case, these specific config settings made more sense to be stored in the registry. I can't be positive that our users will install the applications to the same locations, and at the very least, I'd have to store the location of the "master" config XML file in the registry so the other applications could locate it.
I simply whipped up a class with an index to read/write configuration settings to the registry like a Hashtable (string ponySetting = myRegistryObject["DefaultPonySetting"]) and called it a day. I reference the main assembly with this class in all the other applications anyways. Huzzah
I wouldn't use the registry for sure but for simple application-wide settings I just roll my own XML file in the same location as the EXE and use my own classes to access it. For this sort of thing the setting handling in .NET is way overcomplicated, and it's not even as bad now as it used to be.

Categories