Custom channel factory (WPF)

by naej_94 on September 3rd, 2010
No notes
Syntax: C#
Show lines - Hide lines - Show in textbox - Download
/// <summary>
	/// Custom client channel. Allows to specify a different configuration file
	/// </summary>
	/// <typeparam name="T"></typeparam>
	public class CustomClientChannel<T> : ChannelFactory<T>
	{
		string _configurationPath;
		string _endpointConfigurationName;
                TimeSpan? _timeout = null;
 
		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="configurationPath"></param>
		public CustomClientChannel(string configurationPath) : base(typeof(T))
		{
			this._configurationPath = configurationPath;
			base.InitializeEndpoint((string)null, null);
		}
 
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="configurationPath"></param>
        public CustomClientChannel(string configurationPath, TimeSpan timeout)
            : base(typeof(T))
        {
            this._timeout = timeout;
            this._configurationPath = configurationPath;
            base.InitializeEndpoint((string)null, null);
        }
 
		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="binding"></param>
		/// <param name="configurationPath"></param>
		public CustomClientChannel(Binding binding, string configurationPath)
			: this(binding, (EndpointAddress)null, configurationPath)
 
		{
		}
 
		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="serviceEndpoint"></param>
		/// <param name="configurationPath"></param>
		public CustomClientChannel(ServiceEndpoint serviceEndpoint, string configurationPath)
			: base(typeof(T))
		{
			this._configurationPath = configurationPath;
			base.InitializeEndpoint(serviceEndpoint);
		}
 
		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="endpointConfigurationName"></param>
		/// <param name="configurationPath"></param>
		public CustomClientChannel(string endpointConfigurationName, string configurationPath)
			: this(endpointConfigurationName, null, configurationPath)
		{
		}
 
		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="binding"></param>
		/// <param name="endpointAddress"></param>
		/// <param name="configurationPath"></param>
		public CustomClientChannel(Binding binding, EndpointAddress endpointAddress, string configurationPath)
			: base(typeof(T))
		{
			this._configurationPath = configurationPath;
			base.InitializeEndpoint(binding, endpointAddress);
		}
 
		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="binding"></param>
		/// <param name="remoteAddress"></param>
		/// <param name="configurationPath"></param>
		public CustomClientChannel(Binding binding, string remoteAddress, string configurationPath)
			: this(binding, new EndpointAddress(remoteAddress), configurationPath)
		{
		}
 
		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="endpointConfigurationName"></param>
		/// <param name="endpointAddress"></param>
		/// <param name="configurationPath"></param>
		public CustomClientChannel(string endpointConfigurationName, EndpointAddress endpointAddress, string configurationPath)
			: base(typeof(T))
		{
			this._configurationPath = configurationPath;
			this._endpointConfigurationName = endpointConfigurationName;
			base.InitializeEndpoint(endpointConfigurationName, endpointAddress);
		}
 
		/// <summary>
		/// Loads the serviceEndpoint description from the specified configuration file
		/// </summary>
		/// <returns></returns>
		protected override ServiceEndpoint CreateDescription()
		{
			ServiceEndpoint serviceEndpoint = base.CreateDescription();
 
			if (_endpointConfigurationName != null)
				serviceEndpoint.Name = _endpointConfigurationName;
 
			ExeConfigurationFileMap map = new ExeConfigurationFileMap();
			map.ExeConfigFilename = this._configurationPath;
 
			Configuration config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
			ServiceModelSectionGroup group = ServiceModelSectionGroup.GetSectionGroup(config);
 
			ChannelEndpointElement selectedEndpoint = null;
 
			foreach (ChannelEndpointElement endpoint in group.Client.Endpoints)
			{
				if (endpoint.Contract == serviceEndpoint.Contract.ConfigurationName && 
					(this._endpointConfigurationName == null || this._endpointConfigurationName == endpoint.Name))
				{
					selectedEndpoint = endpoint;
					break;
				}
			}
 
			if (selectedEndpoint != null)
			{
				if (serviceEndpoint.Binding == null)
				{
					serviceEndpoint.Binding = CreateBinding(selectedEndpoint.Binding, group);
				}
 
				if (serviceEndpoint.Address == null)
				{
					serviceEndpoint.Address = new EndpointAddress(selectedEndpoint.Address, GetIdentity(selectedEndpoint.Identity), selectedEndpoint.Headers.Headers);
				}
 
				if (serviceEndpoint.Behaviors.Count == 0 && selectedEndpoint.BehaviorConfiguration != null)
				{
					AddBehaviors(selectedEndpoint.BehaviorConfiguration, serviceEndpoint, group);
				}
 
				serviceEndpoint.Name = selectedEndpoint.Contract;
			}
 
			return serviceEndpoint;
 
		}
 
		/// <summary>
		/// Configures the binding for the selected endpoint
		/// </summary>
		/// <param name="bindingName"></param>
		/// <param name="group"></param>
		/// <returns></returns>
		private Binding CreateBinding(string bindingName, ServiceModelSectionGroup group)
		{
			BindingCollectionElement bindingElementCollection = group.Bindings[bindingName];
			if (bindingElementCollection.ConfiguredBindings.Count > 0)
			{
				IBindingConfigurationElement be = bindingElementCollection.ConfiguredBindings[0];
 
				Binding binding = GetBinding(be);
				if (be != null)
				{
					be.ApplyConfiguration(binding);
				}
                if (_timeout != null)
                {
                    binding.CloseTimeout = (TimeSpan)_timeout;
                    binding.OpenTimeout = (TimeSpan)_timeout;
                    binding.ReceiveTimeout = (TimeSpan)_timeout;
                    binding.SendTimeout = (TimeSpan)_timeout; 
                }
				return binding;
			}
			return null;
		}
 
		/// <summary>
		/// Helper method to create the right binding depending on the configuration element
		/// </summary>
		/// <param name="configurationElement"></param>
		/// <returns></returns>
		private Binding GetBinding(IBindingConfigurationElement configurationElement)
		{
			if (configurationElement is CustomBindingElement)
				return new CustomBinding();
			else if (configurationElement is BasicHttpBindingElement)
				return new BasicHttpBinding();
			else if (configurationElement is NetMsmqBindingElement)
				return new NetMsmqBinding();
			else if (configurationElement is NetNamedPipeBindingElement)
				return new NetNamedPipeBinding();
			else if (configurationElement is NetPeerTcpBindingElement)
				return new NetPeerTcpBinding();
			else if (configurationElement is NetTcpBindingElement)
				return new NetTcpBinding();
			else if (configurationElement is WSDualHttpBindingElement)
				return new WSDualHttpBinding();
			else if (configurationElement is WSHttpBindingElement)
				return new WSHttpBinding();
			else if (configurationElement is WSFederationHttpBindingElement)
				return new WSFederationHttpBinding();
 
			return null;
		}
 
		/// <summary>
		/// Adds the configured behavior to the selected endpoint
		/// </summary>
		/// <param name="behaviorConfiguration"></param>
		/// <param name="serviceEndpoint"></param>
		/// <param name="group"></param>
		private void AddBehaviors(string behaviorConfiguration, ServiceEndpoint serviceEndpoint, ServiceModelSectionGroup group)
		{
            if (!String.IsNullOrEmpty(behaviorConfiguration))
            {
                EndpointBehaviorElement behaviorElement = group.Behaviors.EndpointBehaviors[behaviorConfiguration];
                for (int i = 0; i < behaviorElement.Count; i++)
                {
                    BehaviorExtensionElement behaviorExtension = behaviorElement[i];
                    object extension = behaviorExtension.GetType().InvokeMember("CreateBehavior",
                        BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance,
                        null, behaviorExtension, null);
                    if (extension != null)
                    {
                        serviceEndpoint.Behaviors.Add((IEndpointBehavior)extension);
                    }
                }
            }
		}
 
		/// <summary>
		/// Gets the endpoint identity from the configuration file
		/// </summary>
		/// <param name="element"></param>
		/// <returns></returns>
		private EndpointIdentity GetIdentity(IdentityElement element)
		{
			EndpointIdentity identity = null;
			PropertyInformationCollection properties = element.ElementInformation.Properties;
			if (properties["userPrincipalName"].ValueOrigin != PropertyValueOrigin.Default)
			{
				return EndpointIdentity.CreateUpnIdentity(element.UserPrincipalName.Value);
			}
			if (properties["servicePrincipalName"].ValueOrigin != PropertyValueOrigin.Default)
			{
				return EndpointIdentity.CreateSpnIdentity(element.ServicePrincipalName.Value);
			}
			if (properties["dns"].ValueOrigin != PropertyValueOrigin.Default)
			{
				return EndpointIdentity.CreateDnsIdentity(element.Dns.Value);
			}
			if (properties["rsa"].ValueOrigin != PropertyValueOrigin.Default)
			{
				return EndpointIdentity.CreateRsaIdentity(element.Rsa.Value);
			}
			if (properties["certificate"].ValueOrigin != PropertyValueOrigin.Default)
			{
				X509Certificate2Collection supportingCertificates = new X509Certificate2Collection();
				supportingCertificates.Import(Convert.FromBase64String(element.Certificate.EncodedValue));
				if (supportingCertificates.Count == 0)
				{
					throw new InvalidOperationException("UnableToLoadCertificateIdentity");
				}
				X509Certificate2 primaryCertificate = supportingCertificates[0];
				supportingCertificates.RemoveAt(0);
				return EndpointIdentity.CreateX509CertificateIdentity(primaryCertificate, supportingCertificates);
			}
 
			return identity;
		}
 
        /// <summary>
        /// Applique une configuration selon son nom
        /// </summary>
        /// <param name="configurationName">nom de configuration</param>
		protected override void ApplyConfiguration(string configurationName)
		{
			//base.ApplyConfiguration(configurationName);
		}
	}
 

Leave a Reply

Note: XHTML is allowed. Your email address will never be published.

Subscribe to this comment feed via RSS