Using multiple config files in a Provider Model scenario - c#

We are using a Provider Model for a Payment gateways and I am hoping to figure out a way to do the following;
Each provider should have it's own configuration file. This will contain only the configuration applicable to that provider.
The consumer would have a configuration file that stores only the entries that are required, such as Unity.The consumer would then load the providers via Unity.
We could potentially have a number of Providers and encapsulating the configuration of each means that can be pre-packaged and the only requirement on the consumer would be an alias to the Type and this could then be 'slotted in'.
As far as I can see, there is no way to have multiple configuration files and the provider's configuration is currently being ignored. However, I am hoping that perhaps a workable solution has been found by someone.
Thanks in advance

You can have as many configuration files as you like! Although you can only have one root config file per application, you can externalize most sections of this file into external separate files.
However, in this case, I'd be inclined to use XML files containing a serialized configuration object for each Provider.
Create a factory method to deserialize the config, build the configuration class and create each concrete Provider.
In your application config, just store the information required by the factory, such as the location of the XML configuration file for each provider.
Incidentally (& pedantically) - there is no such thing as a Provider Pattern. The Provider Model is typically implemented by combining Strategy and Factory patterns.

If you want these configuration files to be automatically consumed by the Configuration API in .NET, then to have multiple files you need to reference external configuration files from the central one loaded in the AppDomain on start up:
http://weblogs.asp.net/pwilson/archive/2003/04/09/5261.aspx
The Configuration API only goes looking for one file - this is likely why others are being ignored.
Alternatively, create your own configuration wrapper around the file and access it through this.
Again alternatively, there is nothing wrong with having one file contain all the relevant configuration sections.

Related

Access logger from multiple types of projects, one config file

I have a solution that is a combination of WCF, console applications, services, and ASMX projects. I need a way to have a single log4net config file for all of these projects. I cannot inject a logger into these classes. I'm thinking of a central log manager that wraps log4net.
What's a good way to provide a log manager that allows this?
Also, I also don't want to be reading the config file all the time. I'd rather load it up once the first time it's needed. Especially since this will mean reading it each time an ASMX page is loaded.
Thank you.
You can make a service, then all your projects can log to the service. You will only have one configuration and change all on configuration at one place.

Dynamically generate app configuration as part of CI

We have many environments and thinking of creating dynamic application configuration as part of CI. The configuration values will be stored in Database using WPF. Operation team manages the app for new app config entries.
The problem I am facing is how can I dynamically create the config and validate it? Opinions..? Thanks in advance.
If the number of configurations is finite and known (test, UAT, production desktop, production mobile, etc), you can take advantage of the configSource attribute found on the AppSettings, ConnectionStrings and ConfigSection elements. Here's the basic premise; create an AppSettings.xyz.config file for each configuration, where xyz is the name of the configuration ("local" "test", "uat", "prod", etc). Create a single app.config file that uses a <!ENTITY config "xyz"> definition, and has configSource attributes for various sections set similar to:
<appsettings configSource="appSettings.&config.config">
Now, in deployment logic, you change one thing; the string literal defined by the entity. This change is simple enough that you don't even really need XML parsing to make the change; just slurp the file into memory with a FileStream, find the entity definition, make the change and spit the new content back out into the file. If you're using an installer, you can control which child configs are installed, or just put them all out there for simplicity.
Take a look at T4. You can create a skeleton .config file with certain variables that are filled from the database to generate the environment-specific file.

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.

How to make dynamically generated .net service client read configuration from another location than *.config files

I've currently written code to use the ServiceContractGenerator to generate web service client code based on a wsdl, and then compile it into an assembly in memory using the code dom. I'm then using reflection to set up the binding, endpoint, service values/types, and then ultimately invoke the web service method based on xml configuration that can be altered at run time.
This all currently works fine. However, the problem I'm currently running into, is that I'm hitting several exotic web services that require lots of custom binding/security settings. This is forcing me to add more and more configuration into my custom xml configurations, as well as the corresponding updates to my code to interpret and set those binding/security settings in code.
Ultimately, this makes adding these 'exotic' services slower, and I can see myself eventually reimplementing the 'system.serviceModel' section of the web or app.config file, which is never a good thing.
My question is, and this is where my lack of experience .net and C# shows, is there a way to define the configuration normally found in the web.config or app.config 'system.serviceModel' section somewhere else, and at run time supply this to configuration to the web service client?
Is there a way to attach an app.config directly to an assembly as a resource or any other way to supply this configuration to the client?
Basically, I'd like attach an app.config only containing a 'system.serviceModel' to the assembly containing a web service client so that it can use its configuration. This way I wouldn't need to handle every configuration under the sun, I could let .net do it for me.
Fyi, it's not an option for me to put the configuration for every service in the app.config for the running application.
Any help would be greatly appreciated.
Thanks in advance!
Bryan
Create a custom class deriving from
ChannelFactory.
Override the protected
CreateDescription method. In the
override, you need to...
Call base.CreateDescription().
Read in your custom configuration.
Create a custom ServiceEndpoint based
on your configuration. Don't forget
the bindings, behaviors, etc.
Return that custom ServiceEndpoint.
More details HERE
The following couple links talk about loading WCF Configuration settings from config files other than the app.config. May be what you are looking for but not certain.
http://blogs.msdn.com/dotnetinterop/archive/2008/09/22/custom-service-config-file-for-a-wcf-service-hosted-in-iis.aspx
http://weblogs.asp.net/cibrax/archive/2007/10/19/loading-the-wcf-configuration-from-different-files-on-the-client-side.aspx
Are your proxy classes deriving from ClientBase<T>? If so, then there is a constructor that accepts a Binding and an EndpointAddress. You should be able to use those instead of the corresponding configuration data.

ConfigurationManager.OpenExeConfiguration() vs XML file

Could someone tell me the advantages to using the ConfigurationManager class which load's a config file for manipulation VS an XML file with a class you build to read it yourself?
Recently, I built a class which inherits from ConfigurationSection in order to manipulate a custom section within app.config. This was quite a bit of work compared to just opening and reading an XML file.
Some people chose the first approach, others chose the second.
What's good practice?
This is an old question, but what the hell... so yes, there is quite some code overhead in writing configuration sections and elements, but what you get as compared to using your own class with an XML serializer include:
Type conversions and validations: if one of your configuration settings is, say, a "Type" (maybe you store in your configuration what kind of implementation you need to create for some provider), then the ConfigurationManager will not only convert whatever was written in the .config file to a System.Type, but you can also add validation attribtues on your ConfigurationElement's property, like "SubclassTypeValidatorAttribute", which will check that the given type derives from your base provider class/interface. You can of course add your own validators, so that in the rest of your code, you just "get" the configuration and you know everything's valid.
Multi-level settings hierarchy: you can play around with storing settings at the machine, application or user levels, which gives you a mechanism to handle default vs. user-specific settings. You also have APIs to load configurations from custom locations.
No duplication in config files: if you're using other .NET features like TraceSources and stuff, the configuration for that is already in the .config file (say you're troubleshooting a problem and you want to turn on some debug trace that's off by default... you do that by just modifying the .config). If you're using your own config file for your custom settings, then you end up with 2 configuration files, which is not so good.
There's probably other benefits, but that's what comes to mind so far.
It's just a recommended and easier way of reading and writing data to configuration files. Using XML DOM is too low level.
You can always get raw xml configuration from ConfigurationSection using section.SectionInformation.GetRawXml() if needed. Likewise use SetRawXml to set this.
There are a few gotchas though when using ConfigurationManager, for example when you load a config file using OpenMappedExeConfiguration, you get an in memory configuration which is "merged" and has sections from machine.config. You can check if a section came from the file you provided using section.ElementInformation.Source.Equals(source.FilePath).
Reference: MSDN

Categories