title: creating WCF ChannelFactory<T>
body: <p>I'm trying to convert an existing .NET Remoting application to WCF. Both server and client share common interface and all objects are server-activated objects.</p>
  
  <p>In WCF world, this would be similar to creating per-call service and using <code>ChannelFactory&lt;T&gt;</code> to create a proxy. I'm struggling a bit with how to properly create <code>ChannelFactory&lt;T&gt;</code> for an ASP.NET client. </p>
  
  <p>For performance reasons, I want to cache <code>ChannelFactory&lt;T&gt;</code> objects and just create channel every time I call the service. In .NET remoting days, there used to be <code>RemotingConfiguration.GetRegisteredWellknownClientTypes()</code> method to get a collection of client objects that I could then cache. It appears, in WCF world there is no such thing, although I was able to get a collection of endpoints from config file.</p>
  
  <p>Now here is what I think will work. I can create something like this:</p>
  
  <pre><code>public static ProxyHelper
  {
      static Dictionary&lt;Type, object&gt; lookup = new Dictionary&lt;string, object&gt;();  
  
      static public T GetChannel&lt;T&gt;()
      {
          Type type = typeof(T);
          ChannelFactory&lt;T&gt; factory;
  
          if (!lookup.ContainsKey(type))
          {
              factory = new ChannelFactory&lt;T&gt;();
              lookup.Add(type, factory);
          }
          else
          {
              factory = (ChannelFactory&lt;T&gt;)lookup[type];
          }
  
          T proxy = factory.CreateChannel();   
          ((IClientChannel)proxy).Open();
  
          return proxy;
      }    
  }
  </code></pre>
  
  <p>I think the above code will work, but I'm a bit worried about multiple threads trying to add new <code>ChannelFactory&lt;T&gt;</code> objects if it's not in the lookup. Since I'm using .NET 4.0, I was thinking about using <code>ConcurrentDictionary</code> and use <code>GetOrAdd()</code> method or use <code>TryGetValue()</code> method first to check if <code>ChannelFactory&lt;T&gt;</code> exists and it does not exist, then use <code>GetOrAdd()</code> method. Not sure about performance though of <code>ConcurrentDictionary.TryGetValue()</code> and <code>ConcurrentDictionary.GetOrAdd()</code> method.</p>
  
  <p>Another minor question is whether I need to call <code>ChannelFactory.Close()</code> method on channel factory objects after ASP.NET application ends or can I just let .NET framework dispose the channel factory objects on its own. The proxy channel will always be closed after calling service method by using <code>((IChannel)proxy).Close()</code> method.</p>