Skip to content

Instantly share code, notes, and snippets.

@tracker1
Created May 30, 2013 01:13
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save tracker1/5675161 to your computer and use it in GitHub Desktop.
Save tracker1/5675161 to your computer and use it in GitHub Desktop.
Below is an example of creating a generic WCF Service Client from the interface base, as well as an extension method for Unity.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using System.Configuration;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Runtime.Serialization;
using System.Xml;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using Utility.Wcf
namespace Utility.Unity
{
public static class UnityExtensions
{
/// <summary>Registers a WCF Service Client Type.</summary>
/// <typeparam name="T">The Interface the WCF Service Implements</typeparam>
/// <param name="serviceEndpointUrl">Optional URL for the service Endpoint. Will use an application setting of "SERVICE_URL:Full.Namespace.For.T" by default.</param>
public void RegisterWcfClient<T>(this UnityContainer container, LifetimeManager lm = null, string serviceEndpointUrl = null)
{
if (lm == null) lm = new ContainerControlledLifetimeManager();
container.RegisterType<ChannelFactory<T>>(lm, new InjectionFactory(c => WcfUtility.GetChannelFactory<T>(serviceEndpointUrl)));
container.RegisterType<T>(new InjectionFactory(c => c.Resolve<ChannelFactory<T>>().CreateChannel()));
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Runtime.Serialization;
using System.Xml;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
namespace Utility.Wcf
{
public static class WcfUtility
{
#region Constants
private const int WcfSerializerMaxStringContentLength = (16 * 1024 * 1024); //16MB;
private const int WcfSerializerMaxArrayLength = 65535; //16bit
private const int WcfSerializerMaxBytesPerRead = (16 * 1024 * 1024); //16MB
private const int WcfSerializerMaxDepth = 65535; //16bit;
private const int WcfSerializerMaxNameTableCharCount = 16384; //default 16K
#endregion
#region Factory Generator (GetChannelFactory<T>)
/// <summary>
/// Gets a channel factory for the given service type
/// </summary>
/// <summary>Retrieves a WCF Client for the T interface.</summary>
/// <typeparam name="T">The Interface the WCF Service Implements</typeparam>
/// <param name="serviceEndpointUrl">Optional URL for the service Endpoint. Will use an application setting of "SERVICE_URL:Full.Namespace.For.T" by default.</param>
/// <returns>An instance of the Interface T as a WCF Client.</returns>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", MessageId = "System.String.StartsWith(System.String)"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "0#")]
public static ChannelFactory<T> GetChannelFactory<T>(string serviceEndpointUrl = null)
{
//no serviceEndpontUrl specified
if (string.IsNullOrWhiteSpace(serviceEndpointUrl))
{
//get default from config appsettings
var configSetting = string.Format("SERVICE_URL:{0}", (typeof(T)).FullName);
serviceEndpointUrl = ConfigurationManager.AppSettings[configSetting];
if (string.IsNullOrWhiteSpace(serviceEndpointUrl))
{
//no appsetting, throw exception.
throw new ApplicationException(string.Format("Missing Application Setting for '{0}'", configSetting));
}
}
var endpoint = new EndpointAddress(serviceEndpointUrl);
//http/https binding
if (serviceEndpointUrl.StartsWith("http://") || serviceEndpointUrl.StartsWith("https://"))
{
var binding = new WebHttpBinding();
//raise binding reader quotas to sane limits
binding.ReaderQuotas.MaxStringContentLength = WcfSerializerMaxStringContentLength;
binding.ReaderQuotas.MaxArrayLength = WcfSerializerMaxArrayLength;
binding.ReaderQuotas.MaxBytesPerRead = WcfSerializerMaxBytesPerRead;
binding.ReaderQuotas.MaxDepth = WcfSerializerMaxDepth;
//binding.ReaderQuotas.MaxNameTableCharCount = WcfSerializerMaxNameTableCharCount;
var factory = new ChannelFactory<T>(binding, endpoint);
factory.Endpoint.Behaviors.Add(new WebHttpBehavior());
return factory;
}
//tcp binding
if (serviceEndpointUrl.StartsWith("net.tcp://"))
{
var binding = new NetTcpBinding();
//raise binding reader quotas to sane limits
binding.ReaderQuotas.MaxStringContentLength = WcfSerializerMaxStringContentLength;
binding.ReaderQuotas.MaxArrayLength = WcfSerializerMaxArrayLength;
binding.ReaderQuotas.MaxBytesPerRead = WcfSerializerMaxBytesPerRead;
binding.ReaderQuotas.MaxDepth = WcfSerializerMaxDepth;
//binding.ReaderQuotas.MaxNameTableCharCount = WcfSerializerMaxNameTableCharCount;
var factory = new ChannelFactory<T>(binding, endpoint);
return factory;
}
//local net pipes binding
if (serviceEndpointUrl.StartsWith("net.pipe://"))
{
var binding = new NetNamedPipeBinding();
//raise binding reader quotas to sane limits
binding.ReaderQuotas.MaxStringContentLength = WcfSerializerMaxStringContentLength;
binding.ReaderQuotas.MaxArrayLength = WcfSerializerMaxArrayLength;
binding.ReaderQuotas.MaxBytesPerRead = WcfSerializerMaxBytesPerRead;
binding.ReaderQuotas.MaxDepth = WcfSerializerMaxDepth;
//binding.ReaderQuotas.MaxNameTableCharCount = WcfSerializerMaxNameTableCharCount;
var factory = new ChannelFactory<T>(binding, endpoint);
return factory;
}
//no matching binding for the config
throw new ApplicationException(string.Format("The service end point url specified does not match a supported protocol ({0}).", serviceEndpointUrl));
}
#endregion
}
}
<configuration>
<appSettings>
<!-- WCF Service Client Endpoints -->
<add key="SERVICE_URL:Namespace.For.Interface.ITestService" value="http://localhost:8080/TestService" />
<!--<add key="SERVICE_URL:Namespace.For.Interface.ITestService" value="net.tcp://localhost:999/" />-->
<!--<add key="SERVICE_URL:Namespace.For.Interface.ITestService" value="net.pipe://localhost/TestService" />-->
</appSettings>
</configuration>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment