Search code examples
c#.netwcf.net-4.5

How to get rid of app.config and move it all into code?


I tried this question in a generic way on this post: https://stackoverflow.com/q/18968846/147637

But that did not get us to the result.

Soooo, here it is concretely!

I have the code below. It works. In VS, you add a web reference, code up the below, and then.... start fiddling the app.config.

And it works.

But I need to get rid of the app config. It is a problem that crucial pieces of the code are not in the.... code. It is hard to document, and easy for folks looking at this example to forget to look in the app config (this is an example for other devs).

So the question is: How do I move the contents of app.config into code?

(I am a part part part time coder. Pointing me at generic documentation won't get me there, sorry to say!)

**// .cs file:**

using myNameSpace.joesWebService.WebAPI.SOAP;

namespace myNameSpace
{
    class Program
    {
        static void Main(string[] args)
        {
            // create the SOAP client
            joesWebServerClient server = new joesWebServerClient();

            string payloadXML = Loadpayload(filename);

            // Run the SOAP transaction
            string response = server.WebProcessShipment(string.Format("{0}@{1}", Username, Password), payloadXML);

=================================================
**app.config**

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <!--  Some non default stuff has been added by hand here    -->
                <binding name="IjoesWebServerbinding" maxBufferSize="256000000" maxReceivedMessageSize="256000000" />
            </basicHttpBinding>
        </bindings>
        <client>
          <endpoint address="http://joesWebServer/soap/IEntryPoint"
                    binding="basicHttpBinding" bindingConfiguration="IjoesWebServerbinding"
                    contract="myNameSpace.joesWebService.WebAPI.SOAP.IjoesWebServer"
                    name="IjoesWebServerSOAP" />
        </client>
      </system.serviceModel>
</configuration>

Solution

  • Generally speaking, a config file is preferred over hard-coding the settings because all you need to do with a config file is change the values you want to change and then restart the application. If they're hardcoded, you have to modify the source, recompile and redeploy.

    Having said that, you can pretty much do everything in code that you do in the config file for WCF (I seem to recall a few exceptions, but don't remember them off hand).

    One way to achieve what you're looking for is to define the binding in your code and create the client via ChannelFactory<T>, where T is the interface for your service (more accurately the service contract, which is usually in an interface and then implemented by a class).

    For example:

    using System.ServiceModel;
    using myNameSpace.joesWebService.WebAPI.SOAP;
    
    namespace myNameSpace
    {
        class Program
        {
            static void Main(string[] args)
            {
    
            // Create the binding
            BasicHttpBinding myBinding = new BasicHttpBinding();
            myBinding.MaxBufferSize = 256000000;
            myBinding.MaxReceivedMessageSize = 256000000;
    
            // Create the Channel Factory
            ChannelFactory<IjoesWebServer> factory =
                new ChannelFactory<IjoesWebServer>(myBinding, "http://joesWebServer/soap/IEntryPoint");
    
            // Create, use and close the client
            IjoesWebService client = null;
            string payloadXML = Loadpayload(filename);
            string response;
    
            try
            {
                client = factory.CreateChannel();
                ((IClientChannel)client).Open();
    
                response = client.WebProcessShipment(string.Format("{0}@{1}", Username, Password), payloadXML);
    
                ((IClientChannel)client).Close();
            }
            catch (Exception ex)
            {
                ((ICientChannel)client).Abort();
    
                // Do something with the error (ex.Message) here
            }
        }
    }
    

    Now you don't need a config file. The additional settings you had in the example are now in the code.

    The advantage of ChannelFactory<T> is that once you create an instance of the factory, you can generate new channels (think of them as clients) at will by calling CreateChannel(). This will speed things up as most of your overhead will be in the creation of the factory.

    An additional note - you're using I<name> in a lot of places in your config file. I usually denotes an interface, and if a full time developer were to look at your project it might be a little confusing for them at first glance.