1 //------------------------------------------------------------ 2 // Copyright (c) Microsoft Corporation. All rights reserved. 3 //------------------------------------------------------------ 4 namespace System.ServiceModel.Channels 5 { 6 using System; 7 using System.Threading; 8 using System.Security.Authentication.ExtendedProtection; 9 10 sealed class ChannelBindingMessageProperty : IDisposable, IMessageProperty 11 { 12 const string propertyName = "ChannelBindingMessageProperty"; 13 14 ChannelBinding channelBinding; 15 object thisLock; 16 bool ownsCleanup; 17 int refCount; 18 ChannelBindingMessageProperty(ChannelBinding channelBinding, bool ownsCleanup)19 public ChannelBindingMessageProperty(ChannelBinding channelBinding, bool ownsCleanup) 20 { 21 if (channelBinding == null) 22 { 23 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("channelBinding"); 24 } 25 26 this.refCount = 1; 27 this.thisLock = new object(); 28 this.channelBinding = channelBinding; 29 this.ownsCleanup = ownsCleanup; 30 } 31 32 public static string Name { get { return propertyName; } } 33 34 bool IsDisposed 35 { 36 get 37 { 38 return this.refCount <= 0; 39 } 40 } 41 42 public ChannelBinding ChannelBinding 43 { 44 get 45 { 46 ThrowIfDisposed(); 47 return this.channelBinding; 48 } 49 } 50 TryGet(Message message, out ChannelBindingMessageProperty property)51 public static bool TryGet(Message message, out ChannelBindingMessageProperty property) 52 { 53 if (message == null) 54 { 55 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message"); 56 } 57 58 return TryGet(message.Properties, out property); 59 } 60 TryGet(MessageProperties properties, out ChannelBindingMessageProperty property)61 public static bool TryGet(MessageProperties properties, out ChannelBindingMessageProperty property) 62 { 63 if (properties == null) 64 { 65 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("properties"); 66 } 67 68 property = null; 69 object value; 70 71 if (properties.TryGetValue(ChannelBindingMessageProperty.Name, out value)) 72 { 73 property = value as ChannelBindingMessageProperty; 74 return property != null; 75 } 76 77 return false; 78 } 79 AddTo(Message message)80 public void AddTo(Message message) 81 { 82 if (message == null) 83 { 84 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message"); 85 } 86 87 AddTo(message.Properties); 88 } 89 AddTo(MessageProperties properties)90 public void AddTo(MessageProperties properties) 91 { 92 ThrowIfDisposed(); 93 if (properties == null) 94 { 95 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("properties"); 96 } 97 98 properties.Add(ChannelBindingMessageProperty.Name, this); 99 } 100 CreateCopy()101 public IMessageProperty CreateCopy() 102 { 103 lock (this.thisLock) 104 { 105 ThrowIfDisposed(); 106 this.refCount++; 107 return this; 108 } 109 } 110 Dispose()111 public void Dispose() 112 { 113 if (!this.IsDisposed) 114 { 115 lock (this.thisLock) 116 { 117 if (!this.IsDisposed && --this.refCount == 0) 118 { 119 if (ownsCleanup) 120 { 121 // Accessing via IDisposable to avoid Security check (functionally the same) 122 ((IDisposable)this.channelBinding).Dispose(); 123 } 124 } 125 } 126 } 127 } 128 ThrowIfDisposed()129 void ThrowIfDisposed() 130 { 131 if (this.IsDisposed) 132 { 133 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ObjectDisposedException(this.GetType().FullName)); 134 } 135 } 136 } 137 } 138