How to optimize WCF CreateFactory in System.ServiceModel.ChannelFactory? : <p>My current implementation is utilizing the ClientBase class to create a channel for WCF calls made to a third party API. This third party API requires a X509Certificate2 certificate as well as ClientCredentials to be authenticated. </p>

<pre class="lang-cs prettyprint-override"><code>public class HeaderAdder : ContextBoundObject, IClientMessageInspector
{
    public bool RequestFailedDueToAuthentication;

    public string UserName { get; set; }
    public string Password { get; set; }

    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        var property = new UserNameHeader
        {
            Password = Password,
            UserName = UserName
        };
        request.Headers.Add(MessageHeader.CreateHeader("UserNameHeader", "test", property));
        return null;
    }

    public void AfterReceiveReply(ref Message reply, object correlationState)
    {
        RequestFailedDueToAuthentication = reply.ToString().Contains("ErrorCode&gt;-4&lt;");
    }
}

public class CustomEndpointBehavior : IEndpointBehavior
{
    private readonly HeaderAdder _headerAdder;

    public CustomEndpointBehavior(HeaderAdder headerAdder)
    {
        _headerAdder = headerAdder;
    }

    public void Validate(ServiceEndpoint endpoint)
    {
        //throw new NotImplementedException();
    }

    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {
        //throw new NotImplementedException();
    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {
        //throw new NotImplementedException();
    }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
        var credentials = endpoint.Behaviors.Find&lt;ClientCredentials&gt;();
        if (!string.IsNullOrEmpty(credentials.UserName.Password))
        {
            _headerAdder.UserName = credentials.UserName.UserName;
            _headerAdder.Password = credentials.UserName.Password;
            clientRuntime.ClientMessageInspectors.Add(_headerAdder);
        }
    }
}
</code></pre>

<p><strong>Client instantiation and request can be seen here:</strong></p>

<pre class="lang-cs prettyprint-override"><code>var client = new TestClient()
{
    ClientCredentials =
    {
        UserName =
        {
            UserName = "testing",
            Password = "testing"
        },
        UseIdentityConfiguration = true
    }
};
client.ClientCredentials?.ClientCertificate.SetCertificate(
    StoreLocation.LocalMachine, 
    StoreName.My,
    X509FindType.FindByIssuerName, 
    "Testing");
client.ChannelFactory.Endpoint.EndpointBehaviors.Add(
   new CustomEndpointBehavior(new HeaderAdder()));
var request = new Request();
client.Get(request);
</code></pre>

<p>Unfortunately the process of creating a Channel for the WCF call takes over 9 seconds to complete. Using ReSharper's doTrace profiler I am able to see that the code is being held up on the following method: <strong>System.ServiceModel.Description.XmlSerializer.OperationBehavior+Reflecto.EnsureMessageInfos</strong></p>

<p>A full stack trace of the calls being made in <strong>System.ServiceModel</strong> can be seen below.</p>

<pre><code>System.ServiceModel.ClientBase`1.get_Channel
System.ServiceModel.ClientBase`1.CreateChannelInternal
System.ServiceModel.ClientBase`1.CreateChannel
System.ServiceModel.ChannelFactory`1.CreateChannel
System.ServiceModel.ChannelFactory`1.CreateChannel(EndpointAddress, Uri)
System.ServiceModel.ChannelFactory.EnsureOpened
System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan)
System.ServiceModel.ChannelFactory.OnOpening
System.ServiceModel.ChannelFactory.CreateFactory
System.ServiceModel.Channels.ServiceChannelFactory.BuildChannelFactory(ServiceEndpoint, Boolean)
System.ServiceModel.Description.DispatcherBuilder.BuildProxyBehavior(ServiceEndpoint, out BindingParameterCollection)
System.ServiceModel.Description.DispatcherBuilder.ApplyClientBehavior(ServiceEndpoint, ClientRuntime)
System.ServiceModel.Description.DispatcherBuilder.BindOperations(ContractDescription, ClientRuntime, DispatchRuntime)
System.ServiceModel.Description.XmlSerializerOperationBehavior.ApplyClientBehavior(OperationDescription, ClientOperation)
System.ServiceModel.Description.XmlSerializerOperationBehavior.CreateFormatter
System.ServiceModel.Description.XmlSerializerOperationBehavior+Reflector.EnsureMessageInfos
</code></pre>

<p>I have already tried using sgen.exe to create an XML serialization assembly in hopes that it would improve the serializer's performance. Unfortunately, it had no effect.</p>

<p>I have also found several approaches online that recommend caching Channels, or Channel Factories such as here <a href="http://www.itprotoday.com/microsoft-visual-studio/wcf-proxies-cache-or-not-cache" rel="noreferrer">http://www.itprotoday.com/microsoft-visual-studio/wcf-proxies-cache-or-not-cache</a>. However, these approaches do not work for this implementation because the Channel Factory has Client Credentials associated with it. This would require caching of a Channel Factory or Channel for each client which is unrealistic. </p>

<p>Does anyone know of a way to prevent the ChannelFactory from reflecting over the Request and Response objects when it is created? Any assistance anyone can be provide on this issue would greatly appreciated. </p>
