Setting the Binding and Endpoint configuration in code is one way but there is another way to use the consumer DLL and let the configuration stay in the existing App.config file.
The reason why the mentioned InvalidOperationException occurs is because the DLL does not contain the configuration settings in it. It always rely on App.config to provide for it but since you are using the DLL in another Console application it does not find the configuration settings.
When we use the "Add Service Reference" dialog to add the web service to client component and create instance of the Web service, we let Visual Studio handle the creation of the Communication channel and load the configuration setting.So, if we are able to create such channel explicitly our self then we can manage the configuration settings.
Microsoft provides Classes for this purpose, ConfigurationChannelFactory<TChannel>
Class is one. MSDN states:
Provides the generic functionality to create a channel configuration element for a specific type.
The ConfigurationChannelFactory allows central management of WCF client configuration.
Use "Add Service Reference" dialog to add the web service to client component as we need the Service Channel Interface instance.
First rename the generated App.config file to App.dll.config and in its File properties change the Copy to Output Directory property to Copy Always
Create a class that has a method which returns the Channel object to access the web Service such as this:
public class ManageService
{
public static T CreateServiceClient<T>(string configName)
{
string _assemblyLocation = Assembly.GetExecutingAssembly().Location;
var PluginConfig = ConfigurationManager.OpenExeConfiguration(_assemblyLocation);
ConfigurationChannelFactory<T> channelFactory = new ConfigurationChannelFactory<T>(configName, PluginConfig, null);
var client = channelFactory.CreateChannel();
return client;
}
}
Since we have set the property Copy Always VS copies the Project DLL as well as the App.dll.config into the bin folder. Assembly.GetExecutingAssembly().Location
return the assembly location and ConfigurationManager.OpenExeConfiguration
Opens the specified client configuration file as a Configuration object.
PluginConfig
holds the App.Config configuration file Object and ConfigurationChannelFactory<T>
uses it to communicate with the service.
This method can be called by passing your Service Channel Interface Object like this:
Client = ManageService.CreateServiceClient<SampleService.IKeyServiceChannel>("MetadataExchangeTcpBinding_IKeyService");
SampleService
is the namespace of my web service. Client
holds the instance of the web Service.
If you need to handle Duplex Communication and Callbacks, then you can look at ConfigurationDuplexChannelFactory<TChannel>
Class.