PageRenderTime 43ms CodeModel.GetById 36ms app.highlight 4ms RepoModel.GetById 1ms app.codeStats 0ms

/WCFWebApi/src/Microsoft.ApplicationServer.Http/Microsoft/ApplicationServer/Http/Channels/HttpMessageEncodingBindingElement.cs

#
C# | 155 lines | 89 code | 19 blank | 47 comment | 13 complexity | 7d2afa308335d7015ff609fe8ef5ee42 MD5 | raw file
  1// <copyright>
  2//   Copyright (c) Microsoft Corporation.  All rights reserved.
  3// </copyright>
  4
  5namespace Microsoft.ApplicationServer.Http.Channels
  6{
  7    using System;
  8    using System.Diagnostics.CodeAnalysis;
  9    using System.ServiceModel.Channels;
 10    using Microsoft.Server.Common;
 11
 12    /// <summary>
 13    /// Provides an <see cref="HttpMessageEncoderFactory"/> that returns a <see cref="MessageEncoder"/> 
 14    /// that is able to produce and consume <see cref="HttpMessage"/> instances.
 15    /// </summary>
 16    public sealed class HttpMessageEncodingBindingElement : MessageEncodingBindingElement
 17    {
 18        private static readonly Type IReplyChannelType = typeof(IReplyChannel);
 19        private static readonly Type httpMessageEncodingBindingElementType = typeof(HttpMessageEncodingBindingElement);
 20        private static readonly Type channelFactoryType = typeof(IChannelFactory);
 21
 22        /// <summary>
 23        /// Gets or sets the message version that can be handled by the message encoders produced by the message encoder factory.
 24        /// </summary>
 25        /// <returns>The <see cref="MessageVersion"/> used by the encoders produced by the message encoder factory.</returns>
 26        public override MessageVersion MessageVersion
 27        {
 28            get
 29            {
 30                return MessageVersion.None;
 31            }
 32
 33            set
 34            {
 35                if (value == null)
 36                {
 37                    throw Fx.Exception.ArgumentNull("value");
 38                }
 39
 40                if (value != MessageVersion.None)
 41                {
 42                    throw Fx.Exception.AsError(
 43                        new NotSupportedException(
 44                                SR.OnlyMessageVersionNoneSupportedOnHttpMessageEncodingBindingElement(
 45                                    typeof(HttpMessageEncodingBindingElement))));
 46                }
 47            }
 48        }
 49
 50        /// <summary>
 51        /// Returns a value that indicates whether the binding element can build a listener for a specific type of channel.
 52        /// </summary>
 53        /// <typeparam name="TChannel">The type of channel the listener accepts.</typeparam>
 54        /// <param name="context">The <see cref="BindingContext"/> that provides context for the binding element</param>
 55        /// <returns>true if the <see cref="IChannelListener&lt;TChannel&gt;"/> of type <see cref="IChannel"/> can be built by the binding element; otherwise, false.</returns>
 56        [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "Existing public API")]
 57        public override bool CanBuildChannelFactory<TChannel>(BindingContext context)
 58        {
 59            return false;
 60        }
 61
 62        /// <summary>
 63        /// Returns a value that indicates whether the binding element can build a channel factory for a specific type of channel.
 64        /// </summary>
 65        /// <typeparam name="TChannel">The type of channel the channel factory produces.</typeparam>
 66        /// <param name="context">The <see cref="BindingContext"/> that provides context for the binding element</param>
 67        /// <returns>ALways false.</returns>
 68        [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "Existing public API")]
 69        public override IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context)
 70        {
 71            throw Fx.Exception.AsError(
 72                new NotSupportedException(
 73                    SR.ChannelFactoryNotSupported(httpMessageEncodingBindingElementType.Name, channelFactoryType.Name)));
 74        }
 75
 76        /// <summary>
 77        /// Returns a value that indicates whether the binding element can build a channel factory for a specific type of channel.
 78        /// </summary>
 79        /// <typeparam name="TChannel">The type of channel the channel factory produces.</typeparam>
 80        /// <param name="context">The <see cref="BindingContext"/> that provides context for the binding element</param>
 81        /// <returns>ALways false.</returns>
 82        [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "Existing public API")]
 83        public override bool CanBuildChannelListener<TChannel>(BindingContext context)
 84        {
 85            if (context == null)
 86            {
 87                throw Fx.Exception.ArgumentNull("context");
 88            }
 89
 90            context.BindingParameters.Add(this);
 91
 92            return IsChannelShapeSupported<TChannel>() && context.CanBuildInnerChannelListener<TChannel>();
 93        }
 94
 95        /// <summary>
 96        /// Initializes a channel listener to accept channels of a specified type from the binding context.
 97        /// </summary>
 98        /// <typeparam name="TChannel">The type of channel the listener is built to accept.</typeparam>
 99        /// <param name="context">The <see cref="BindingContext"/> that provides context for the binding element</param>
100        /// <returns>The <see cref="IChannelListener&lt;TChannel&gt;"/> of type <see cref="IChannel"/> initialized from the context.</returns>
101        [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "Existing public API")]
102        public override IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context)
103        {
104            if (context == null)
105            {
106                throw Fx.Exception.ArgumentNull("context");
107            }
108
109            if (!IsChannelShapeSupported<TChannel>())
110            {
111                throw Fx.Exception.AsError(
112                    new NotSupportedException(
113                        SR.ChannelShapeNotSupported(httpMessageEncodingBindingElementType.Name, typeof(TChannel).Name, typeof(IReplyChannel).Name)));
114            }
115
116            context.BindingParameters.Add(this);
117
118            IChannelListener<IReplyChannel> innerListener = context.BuildInnerChannelListener<IReplyChannel>();
119
120            if (innerListener == null)
121            {
122                return null;
123            }
124            
125            return (IChannelListener<TChannel>)new HttpMessageEncodingChannelListener(context.Binding, innerListener);
126        }
127
128        /// <summary>
129        /// Returns a copy of the binding element object.
130        /// </summary>
131        /// <returns>A <see cref="BindingElement"/> object that is a deep clone of the original.</returns>
132        public override BindingElement Clone()
133        {
134            return new HttpMessageEncodingBindingElement();
135        }
136
137        /// <summary>
138        /// Creates a factory for producing message encoders that are able to 
139        /// produce and consume <see cref="HttpMessage"/> instances.
140        /// </summary>
141        /// <returns>
142        /// The <see cref="MessageEncoderFactory"/> used to produce message encoders that are able to 
143        /// produce and consume <see cref="HttpMessage"/> instances.
144        /// </returns>
145        public override MessageEncoderFactory CreateMessageEncoderFactory()
146        {
147            return new HttpMessageEncoderFactory();
148        }
149
150        private static bool IsChannelShapeSupported<TChannel>()
151        {
152            return typeof(TChannel) == IReplyChannelType;
153        }
154    }
155}