Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Here's a helper class that I use to handle channel factories:</p> <pre><code>public class ChannelFactoryManager : IDisposable { private static Dictionary&lt;Type, ChannelFactory&gt; _factories = new Dictionary&lt;Type,ChannelFactory&gt;(); private static readonly object _syncRoot = new object(); public virtual T CreateChannel&lt;T&gt;() where T : class { return CreateChannel&lt;T&gt;("*", null); } public virtual T CreateChannel&lt;T&gt;(string endpointConfigurationName) where T : class { return CreateChannel&lt;T&gt;(endpointConfigurationName, null); } public virtual T CreateChannel&lt;T&gt;(string endpointConfigurationName, string endpointAddress) where T : class { T local = GetFactory&lt;T&gt;(endpointConfigurationName, endpointAddress).CreateChannel(); ((IClientChannel)local).Faulted += ChannelFaulted; return local; } protected virtual ChannelFactory&lt;T&gt; GetFactory&lt;T&gt;(string endpointConfigurationName, string endpointAddress) where T : class { lock (_syncRoot) { ChannelFactory factory; if (!_factories.TryGetValue(typeof(T), out factory)) { factory = CreateFactoryInstance&lt;T&gt;(endpointConfigurationName, endpointAddress); _factories.Add(typeof(T), factory); } return (factory as ChannelFactory&lt;T&gt;); } } private ChannelFactory CreateFactoryInstance&lt;T&gt;(string endpointConfigurationName, string endpointAddress) { ChannelFactory factory = null; if (!string.IsNullOrEmpty(endpointAddress)) { factory = new ChannelFactory&lt;T&gt;(endpointConfigurationName, new EndpointAddress(endpointAddress)); } else { factory = new ChannelFactory&lt;T&gt;(endpointConfigurationName); } factory.Faulted += FactoryFaulted; factory.Open(); return factory; } private void ChannelFaulted(object sender, EventArgs e) { IClientChannel channel = (IClientChannel)sender; try { channel.Close(); } catch { channel.Abort(); } throw new ApplicationException("Exc_ChannelFailure"); } private void FactoryFaulted(object sender, EventArgs args) { ChannelFactory factory = (ChannelFactory)sender; try { factory.Close(); } catch { factory.Abort(); } Type[] genericArguments = factory.GetType().GetGenericArguments(); if ((genericArguments != null) &amp;&amp; (genericArguments.Length == 1)) { Type key = genericArguments[0]; if (_factories.ContainsKey(key)) { _factories.Remove(key); } } throw new ApplicationException("Exc_ChannelFactoryFailure"); } public void Dispose() { Dispose(true); } protected virtual void Dispose(bool disposing) { if (disposing) { lock (_syncRoot) { foreach (Type type in _factories.Keys) { ChannelFactory factory = _factories[type]; try { factory.Close(); continue; } catch { factory.Abort(); continue; } } _factories.Clear(); } } } } </code></pre> <p>Then I define a service invoker:</p> <pre><code>public interface IServiceInvoker { R InvokeService&lt;T, R&gt;(Func&lt;T, R&gt; invokeHandler) where T: class; } </code></pre> <p>and an implementation:</p> <pre><code>public class WCFServiceInvoker : IServiceInvoker { private static ChannelFactoryManager _factoryManager = new ChannelFactoryManager(); private static ClientSection _clientSection = ConfigurationManager.GetSection("system.serviceModel/client") as ClientSection; public R InvokeService&lt;T, R&gt;(Func&lt;T, R&gt; invokeHandler) where T : class { var endpointNameAddressPair = GetEndpointNameAddressPair(typeof(T)); T arg = _factoryManager.CreateChannel&lt;T&gt;(endpointNameAddressPair.Key, endpointNameAddressPair.Value); ICommunicationObject obj2 = (ICommunicationObject)arg; try { return invokeHandler(arg); } finally { try { if (obj2.State != CommunicationState.Faulted) { obj2.Close(); } } catch { obj2.Abort(); } } } private KeyValuePair&lt;string, string&gt; GetEndpointNameAddressPair(Type serviceContractType) { var configException = new ConfigurationErrorsException(string.Format("No client endpoint found for type {0}. Please add the section &lt;client&gt;&lt;endpoint name=\"myservice\" address=\"http://address/\" binding=\"basicHttpBinding\" contract=\"{0}\"/&gt;&lt;/client&gt; in the config file.", serviceContractType)); if (((_clientSection == null) || (_clientSection.Endpoints == null)) || (_clientSection.Endpoints.Count &lt; 1)) { throw configException; } foreach (ChannelEndpointElement element in _clientSection.Endpoints) { if (element.Contract == serviceContractType.ToString()) { return new KeyValuePair&lt;string, string&gt;(element.Name, element.Address.AbsoluteUri); } } throw configException; } } </code></pre> <p>Now every time you need to call a WCF service you could use this:</p> <pre><code>WCFServiceInvoker invoker = new WCFServiceInvoker(); SomeReturnType result = invoker.InvokeService&lt;IMyServiceContract, SomeReturnType&gt;( proxy =&gt; proxy.SomeMethod() ); </code></pre> <p>This assumes that you've defined a client endpoint for the <code>IMyServiceContract</code> service contract in the config file:</p> <pre><code>&lt;client&gt; &lt;endpoint name="myservice" address="http://example.com/" binding="basicHttpBinding" contract="IMyServiceContract" /&gt; &lt;/client&gt; </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload