1 //------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation. All rights reserved.
3 //------------------------------------------------------------
5 namespace System.ServiceModel.Channels
7 using System.Collections.Generic;
8 using System.ComponentModel;
9 using System.Runtime.Serialization;
10 using System.ServiceModel;
11 using System.ServiceModel.Description;
12 using System.ServiceModel.Security;
16 public sealed class CompositeDuplexBindingElement : BindingElement, IPolicyExportExtension
18 Uri clientBaseAddress;
20 public CompositeDuplexBindingElement()
24 CompositeDuplexBindingElement(CompositeDuplexBindingElement elementToBeCloned)
25 : base(elementToBeCloned)
27 this.clientBaseAddress = elementToBeCloned.ClientBaseAddress;
31 public Uri ClientBaseAddress
35 return this.clientBaseAddress;
40 this.clientBaseAddress = value;
44 public override BindingElement Clone()
46 return new CompositeDuplexBindingElement(this);
49 public override IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context)
53 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
56 if (typeof(TChannel) != typeof(IOutputChannel))
58 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("TChannel",
59 SR.GetString(SR.ChannelTypeNotSupported, typeof(TChannel)));
62 return context.BuildInnerChannelFactory<TChannel>();
65 public override IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context)
69 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
72 if (typeof(TChannel) != typeof(IInputChannel))
74 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("TChannel",
75 SR.GetString(SR.ChannelTypeNotSupported, typeof(TChannel)));
78 if (context.ListenUriBaseAddress == null)
80 if (this.clientBaseAddress != null)
82 context.ListenUriBaseAddress = this.clientBaseAddress;
83 context.ListenUriRelativeAddress = Guid.NewGuid().ToString();
84 context.ListenUriMode = ListenUriMode.Explicit;
89 #pragma warning suppress 56506 // Microsoft, context.Binding will never be null.
90 context.ListenUriRelativeAddress = String.Empty;
91 context.ListenUriMode = ListenUriMode.Unique;
95 return context.BuildInnerChannelListener<TChannel>();
98 public override bool CanBuildChannelFactory<TChannel>(BindingContext context)
102 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
105 return (typeof(TChannel) == typeof(IOutputChannel))
106 && context.CanBuildInnerChannelFactory<IOutputChannel>();
109 public override bool CanBuildChannelListener<TChannel>(BindingContext context)
113 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
116 return (typeof(TChannel) == typeof(IInputChannel))
117 && context.CanBuildInnerChannelListener<IInputChannel>();
120 ChannelProtectionRequirements GetProtectionRequirements()
122 ChannelProtectionRequirements result = new ChannelProtectionRequirements();
123 XmlQualifiedName refPropHeaderName = new XmlQualifiedName(XD.UtilityDictionary.UniqueEndpointHeaderName.Value,
124 XD.UtilityDictionary.UniqueEndpointHeaderNamespace.Value);
125 MessagePartSpecification headerParts = new MessagePartSpecification(refPropHeaderName);
126 headerParts.MakeReadOnly();
127 result.IncomingSignatureParts.AddParts(headerParts);
128 result.OutgoingSignatureParts.AddParts(headerParts);
132 public override T GetProperty<T>(BindingContext context)
136 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
138 if (typeof(T) == typeof(ISecurityCapabilities))
140 ISecurityCapabilities lowerCapabilities = context.GetInnerProperty<ISecurityCapabilities>();
141 if (lowerCapabilities != null)
143 // composite duplex cannot ensure that messages it receives are from the part it sends
144 // messages to. So it cannot offer server auth
145 return (T)(object)(new SecurityCapabilities(lowerCapabilities.SupportsClientAuthentication,
146 false, lowerCapabilities.SupportsClientWindowsIdentity, lowerCapabilities.SupportedRequestProtectionLevel,
147 System.Net.Security.ProtectionLevel.None));
154 else if (typeof(T) == typeof(ChannelProtectionRequirements))
156 ChannelProtectionRequirements myRequirements = this.GetProtectionRequirements();
157 myRequirements.Add(context.GetInnerProperty<ChannelProtectionRequirements>() ?? new ChannelProtectionRequirements());
158 return (T)(object)myRequirements;
162 return context.GetInnerProperty<T>();
166 internal override bool IsMatch(BindingElement b)
173 CompositeDuplexBindingElement duplex = b as CompositeDuplexBindingElement;
179 return (this.clientBaseAddress == duplex.clientBaseAddress);
182 void IPolicyExportExtension.ExportPolicy(MetadataExporter exporter, PolicyConversionContext context)
185 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
187 exporter.State[typeof(SupportedAddressingMode).Name] = SupportedAddressingMode.NonAnonymous;
188 context.GetBindingAssertions().Add(CreateCompositeDuplexAssertion());
191 static XmlElement CreateCompositeDuplexAssertion()
193 XmlDocument doc = new XmlDocument();
194 return doc.CreateElement(TransportPolicyConstants.CompositeDuplexPrefix, TransportPolicyConstants.CompositeDuplex, TransportPolicyConstants.CompositeDuplexNamespace);