I've set up my VSTO Excel add-in to use log4net for logging. Unfortunately I'm (seemingly) not able to make it configure itself from the app.config (which I deliver together with the add-in via ClickOnce).
I have read http://www.darinhiggins.com/?p=13 which lists some ways to get the file name of the app.config and then configure log4net with
log4net.Config.XmlConfigurator.Configure(fileInfo)
However the approaches this blog lists seem very error-prone to me (they "smell bad").
Things like
ConfigurationManager.GetSection
make me believe the .NET framework knows exactly where to get the file and there must be a way to retrieve this information from the framework instead of having to figure it out on my own. However, the XmlConfigurator in turn only accepts a file name, stream or xml node...
(Why I believe it's not working at the moment: I have configured it to use a RollingFileAppender with the file name being H:\Data\Debug.log, but after a GetLogger(...).Debug(...), there is still no Debug.log in place...). I have used the exact same configuration in other places, successfully.
XmlConfigurator.Configure(); uses the app.config file. That should work since the ConfigurationManager seems to be able to read the config file.
Related
We are a group of C#/.NET 4.5 developers working on the same application.
The application has a set of configurations related to each developer machine, like the connection string to the DB, network related settings (proxies, IPs, credentials) and a LOT MORE.
Because the application has grown we are incurring in a lot of environment related configurations like for example:
If this is MyPC then load the connection string for my PC.
If this is the XDeveloperPC then specify proxy’s settings.
Also if new developers leaves or join the group, then the process to update the file becomes a total head ache. Maintaining the file has become very hard and is a possible source of bug and errors.
I was thinking in having specific app.config files related to each developer environment like:
app_MyPC.config
app_XDeveloperPC.config
And when the application builds or executes then specify which one to load as if it where the default app.config of the application. Then, when the application or any class or method refers to a given configuration (like the connection string) is access to this configuration file as if it where accessing to the app.config default file.
I would not want to create a Configuration class that builds immediately when the application starts because then I should have references from every place to this class and the application is quite large, with a bunch of projects and dlls.
I rather prefer to hear some opinions and what do you think should be the best way to achieve this.
Is it possible to achieve this?
How?
Do you know a better approach?
FYI, please note that .NET only loads one config file for the whole application. You could try multiple config files something as like specified here,
Multiple App.Config Files in .NET Class library project
Hope this helps...
You can specify sections of app.config to be loaded from another file. See this answer
However, you might have to customize the above solution, the app.config files and the way configs are organized.
Another approach is to use a custom settings file instead of app.config. This will need some code change to use the config file. This config can either be an XML or a JSON file (JSON is easy to deal with). You can use an inheritance model wherein generic settings come from one file, specific settings come from another file and so on. Also, you can load settings from such file at runtime and change application behavior on the fly.
If you decide to use custom config file, and if you already have lot of code written considering App.config file, you can abstract the app.config calls to a method and let that method deal with where to pull the settings value from. That way you can minimize the code change and keep everything tidy.
Maybe you can use the machine.config file (C:\Windows\Microsoft.NET\Framework\your Framework version\Config\machine.config)
I've always used my own format of configuration files which is XML and then I just deserialise the XML into an object in my project or just read it into an XML document.
This seems alot easier to read and access the information I need.
I've had a look at the ConfigurationManager class this morning and it seems a bit overly complicated just to read a config file.
Is there any argument as to why I should use ConfigurationManager?
It is just a built-in mechanism in .NET which is already implemented for you, so you don't need any extra code (probably except for wrapping it in your own IConfig to separate concerns).
There is a GUI for editing .NET configuration files which sometimes comes in handy.
ASP.NET application, for instance, automatically restart when web.config has been changed, while you would need some custom logic to have the same behaviour with your own config files.
The ConfigurationManager is used internally and you're not obligated in any way to use it, and I used to do what you do. Nowadays it depends, if it is a file a user is supposed to change I might still do my own configuration, otherwise the file is added as an embedded resource and I use the ConfigurationManager to read it, because I don't think there is another way of reading those files. The thing is, use whatever mechanism you feel like, ConfigurationManager provides a bit more encapsulation though and out of the box utils classes.
I essentially am in charge of a DLL for my project that uses lots of external resources. I want to have a config file for my project named infrastructure.config that clients projects can copy in their project without having to cut and paste into their own app or web configs. I tried the following suggestion at:
Change default app.config at runtime
That solution worked well until I tried with Log4Net which utilizes a custom section. I received an unknown configuration section when I tried to use the code in the above mentioned link. When I use the same configuration file without the above mentioned code it works fine. Interestingly enough, it blew up when I was trying to use TransactionScope. So some combination of using TransactionScope and having configurationSections in my config made it fail. Any suggestions?
I want each client app or web site to have their own config for its own values while my infrsatucture.dll should be able to have a combination of its own values, custom SOAP Bindings and Log4Net.
Sound like what Dependency Injection is good for solving.
I would highly suggest that instead of creating an application/dll that relies on a config file (app settings or sections), that your interface expose what it needs to do it's work. These can be external class/interfaces exposed by other DLLs (log4net) or you can create your own and allow other developers to derive concrete classes based on your required abstract/interfaces classes.
Normally, Unity (the DIC) is configured using an standard XML configuration file, such as web.config.
For the purpose of the project, Unity offers great functionality which I would be loving to use. However, since other customers might want to use it, and not all of them will desire to use an XML config file, there is a wish to be able to create adapters, so that the customer can load his/her own configuration the way (s)he wants it.
So, loading the config from a txt, from a custom xml file, from an standard web.config file, or more importantly, from a database schema defined by them, according to their needs. So that all the mappings for the container are on any of those ways.
I was thinking about what was the best way to do this. Probably will end up doing it in a custom way.
Opinions or other tools that compete with Unity that allow this?
Thanks!
The Unity API lets you do everything you can do in the config file. In fact, the config file loader simply reads the instructions and calls the corresponding API.
My first suggestion would be to consider using the API to configure the container in stead of a config file. Second, if you do want to load config from somewhere else, then simply write a reader for whatever format you want, and call the container API based on what you loaded.
There's nothing in the "box" to read config from other sources, but it's easy to write.
One way would be to use reflection to turn type names, stored as strings in the DB, into type instances. Unity can then be configured at application start-up by programatically loading the type mappings into the container.
I don't have VS open at the moment, but I think the syntax would be something like:
var mapFrom = typeof(IMyInterface);
var mapTo = Type.GetType("My.App.MyType"); // load the string from the DB
var container = new UnityContainer();
container.RegisterType(mapFrom, mapTo);
You might also want to look at Microsoft MEF. It doesn't do exactly what you are talking about, but it is more designed around plug-in architectures, and being able to just drop different .dlls into a folder and have the app automatically use them.
We are running multiple instances of our service (implemented as a .exe file) on different machines in our data center. However, we would like to store configuration parameters for this .exe file in a central location (as opposed to being in the .exe.config per machine).
To do this, we are planning to move the content of the .exe.config files to an attribute in a central repository (Active Directory or SQL) and make the .exe's running on all machines read from this repository.
I would like reuse all the existing classes used for reading/writing configuration information (using ConfigurationManager, ConfigurationProperty etc., basically using the entire .NET Configuration framework) - however, instead of loading it from the .exe.config file (which it does by default - I want it to load it from a string value of the XML blob that I will retrieve from that central repository.
I was trying to find ways to do it using the ConfigurationManager API but couldn't find anything that could load a Configuration Section from a string. Any pointers?
I suppose you could write your own ConfigurationSection that will then load the real config data from your central repository.
Alternatively, do you have some sort of centralized deployment system in place for installing software on your various servers? How does your service get deployed? Rather than adding complexity to your software you should look for existing tools that already solve your problem.
Although I doubt this is what it was intended for, we've done this in our project using ProtectedConfigurationProvider. Basically, this class is supposed to allow you to encrypt your configuration file but we simply have the Decrypt method connect to our database and return the configuration information. See this for notes on implementing. This felt a little hacky, but we couldn't find any other way without completely rewriting all of the configuration parsing logic.