How can I translate my programmatic WCF configuration into app.config - c#

I have an self hosted WCF server with hard coded configurations. the server worked fine until I tried to implement some new configurations functionality (changed ports, added ssl) the new config setting did not work (urrr.... ) and I find it hard to locate where are the problems in my code.
instead of digging inside the code that declares the WCF object, I thought about different approach:
Is there any way to dump-to-file those hard coded WCF configuration (the entire ) into app.config like text file after all configurations are loaded? this will enable me to have a easy global view of the entire settings ..
mmm .. .by the way, does anyone know a way that will do the translation to the opposite direction? config to code.
Any advice will be welcomed!
ofer

I don't think you will find an automatic way to dump your c#/vb code somewhere and have your configuration converted to the config file xml schema (and vice-versa), however if you ask my personal opinion, if you don't have a strong reason to hard-code your configuration in your code (even if you do so, I would rethink that), you should move the wcf configuration out from your code. Configuration is not responsibility of the code. It is configuration, meaning that if you need to change the "configuration", you don't need a new build.
In your code, you should just concentrate in the service consumption logic, leaving the configuration to the back-end engine take care of it. Remember that sometimes you may need adjust some settings, like service throttling, max/min buffer size, MaxItemsInObjectGraph quota, etc. If hard-coded, means a new deployment. If in a config file or other repository, means a simple configuration change.
If you have all your configuration in a config file, when you move your code from environment to environment (Dev, DIT, QA, UAT, Pre-Prod, Production), you can have different settings between environments, if required (because the port number you used is already in use or is blocked in the firewall). The release management team will just configure it properly in the config file.
If you want more control over your service configuration, you could consider creating a factory service for your services, where will get all your configuration from a centralized place (database, xml file, etc), and you will configure your code on-the-fly.
I hope it helps...

Related

Split application-specific and customer-specific web.config parts

We have a web application running on-premise at a variety of customers. The web.config contains lots of
stuff which is "part of our application" (such as most of the <system.web> and <system.webServer> blocks) and
stuff which needs to be customized (connection strings, app settings, and various custom tags).
During updates, part 1 should be replaced and part 2 should be left as it is. Ideally, I'd have a web.app.config and a web.custom.config, so I can replace only the first one. Of course, IIS would need to magically "merge" those at run time, which it does not do.
I found the following approaches:
Put the custom stuff in external files, i.e. <appSettings configSource="appSettings.config"/>.
I cannot use that, because it can only be used for complete sections. But, for example, the aspnet:MaxHttpCollectionKeys setting is a value that should be controlled by the application, whereas other app settings values should be customizable.
Parameterization or Web.Config Transformation.
I cannot use that, because our customers have various versions of our application installed. Thus, I need to replace the application-specific parts of web.config rather than transforming individual tags. In addition, I'd like to avoid adding msdeploy to our deployment process (xcopy plus some scripts to create the IIS apps and configure them work great at the moment). Oh, and I'd still have one big web.config with application-specific and customer-specific stuff meshed together.
Is there some elegant solution that I've missed?
It's true that configSource is used for complete sections, but appSettings has a special attribute called file which can be used to reference a file to be 'merged' into the appSettings list. See https://msdn.microsoft.com/en-AU/library/ms228154(v=vs.85).aspx for more details. I've used extensively to merge in an appSettings.config file with environment specific values - either local dev values (as contained in the repo) or a file that is dumped onto the server with environment specific settings. Helpful when promoting a build artifact through qa, uat, prod environments etc. For you, that file could contain your customer specific values and would not change when you deploy updates.
An alternative approach would be to refactor your customer specific configuration into a Custom Configuration Section. As well as giving you typed access to the configuration values, you can load it from a section in the web.config, load it from a section in the web.config that references another file via configSource, or you can load it directly from a separate file.
You can then leave your application configuration in the appSettings, or move it into a separate custom configuration section.

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.

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.

SharePoint SPItemEventReceiver environment configuration

I have a class that inherits from SPItemEventReceiver and implements ItemAdded, ItemUpdated, and ItemDeleted. These all work just fine and I'm getting the data I need.
However, I want to push some of the data to a 3rd party server via a web service. What is the best way to configure the external dependency of the web service for various environments (dev/test/production) without hard-coding the end point for each environment?
I'd prefer to avoid any static *.ini type files if possible. Can I add a configuration section to SharePoint's web.config and read it from the event handler?
Yes, best place to store that settings is web.config file. Below, some related articles:
Event handlers configuration settings best practices
Reading Settings from the Web.Config file from an Event Handler
Think of it like that - what would happen if you created yet another site of the same type and having the same event receiver and everything. Would you still use the same configuration? Is it a setting per each list? Per website? Per server farm? If you decide it's a server farm setting, then web.config is good for you. If you think that each web needs different config, then you have to persist the configuration somewhere else. For instance, if it's at web level, you can write your config string to SPWeb.Properties. This setting can later be read easily from that object, for instance SPContext.Current.Web.Properties["RemoteWebServiceURL"]. You can also set the value form a tiny PowerShell script. A SPList object has a similar property bag.

Categories