.NET - deploying a WCF client, without an app.conf

2020-02-17 10:17发布

问题:

I'm writing a client to a WCF service. This is a single app in a larger system that includes modules written in C#, C++, VB, and Java. All of the apps share common configuration and logging mechanisms, regardless of what language they were written in.

I'd like to figure out how to build the client application so that it will run without an app.config. Why? Because most of what is in the app.config is boilerplate that the sysadmins shouldn't be allowed to change, and what settings the sysadmins should be allowed to change should be in the system-wide configuration, and not in an app.config file sitting in the bin directory.

Case in point - the client's app.config currently looks like this:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <bindings>
      <customBinding>
        <binding name="WSHttpBinding_ICourierService">
          <security defaultAlgorithmSuite="Default" authenticationMode="SecureConversation"
            ...
          </security>
          <textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16"
            messageVersion="Default" writeEncoding="utf-8">
            <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647"
              maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
          </textMessageEncoding>
          <httpTransport manualAddressing="false"
            ...
            useDefaultWebProxy="true" />
        </binding>
      </customBinding>
    </bindings>
    <client>
      <endpoint address="http://localhost:57102/MyService.svc"
        ...
        >
        <identity>
          <dns value="localhost" />
        </identity>
      </endpoint>
    </client>
  </system.serviceModel>
</configuration>

It's a bunch of opaque boilerplate that the sysadmins shouldn't have to deal with. Most of it was inserted by Visual Studio. I've made one change in the file - I increased the max size in <readerQuotas/>. But that's a change that I don't want the sysadmins to mess with. And there's nothing else in the file I want the sysadmins to mess with except for <endpoint address=""/>.

And I'm pulling the endpoint address from the system-wide configuration, and setting it in code. There's nothing in this file that should be user-editable.

So, how do I configure things so that I don't need to have it present?

Can I embed it as a resource in the assembly, and hook into the app.config load process, the way I do with required DLLs?

Is the only choice to create code to configure things, the way I'm using code to set the endpoint address? Create the necessary bindings, etc., in code? How, then, do I know what code to write, given these chunks of opaque XML?

回答1:

You can use the following code to creating the bindings which is what the config is doing. I am not sure whether that will let you remove the file altogether but the application won't use the config if this is the case. Put your own values in the timeouts, etc.

    var binding = new WSHttpBinding();
    binding.SendTimeout = new TimeSpan(0, 0, 0, 0, 100000);
    binding.OpenTimeout = new TimeSpan(0, 0, 0, 0, 100000);
    binding.MaxReceivedMessageSize = 10000;
    binding.ReaderQuotas.MaxStringContentLength = 10000;
    binding.ReaderQuotas.MaxDepth = 10000;
    binding.ReaderQuotas.MaxArrayLength = 10000;
    var endpoint = new EndpointAddress("http://localhost:57102/MyService.svc");
    var myClient = new WebServiceclient(binding, endpoint);


回答2:

WCF settings can be set in your code, with no need for an external configuration file. Addresses, bindings, endpoints, security, etc. can all be configured in code. This is the best way to be consistent across all of your WCF services and not allow users to tamper with these settings.

I suggest you expose the address (host name and port number) to users and allow them to configure this somehow because addresses are specific to where your WCF services are hosted.