|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Security.Authentication.ExtendedProtection;
namespace System.ServiceModel.Channels
{
internal sealed class ChannelBindingMessageProperty : IDisposable, IMessageProperty
{
private const string propertyName = "ChannelBindingMessageProperty";
private ChannelBinding _channelBinding;
private object _thisLock;
private bool _ownsCleanup;
private int _refCount;
public ChannelBindingMessageProperty(ChannelBinding channelBinding, bool ownsCleanup)
{
if (channelBinding == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("channelBinding");
}
_refCount = 1;
_thisLock = new object();
_channelBinding = channelBinding;
_ownsCleanup = ownsCleanup;
}
public static string Name { get { return propertyName; } }
private bool IsDisposed
{
get
{
return _refCount <= 0;
}
}
public ChannelBinding ChannelBinding
{
get
{
ThrowIfDisposed();
return _channelBinding;
}
}
public static bool TryGet(Message message, out ChannelBindingMessageProperty property)
{
if (message == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message");
}
return TryGet(message.Properties, out property);
}
public static bool TryGet(MessageProperties properties, out ChannelBindingMessageProperty property)
{
if (properties == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("properties");
}
property = null;
object value;
if (properties.TryGetValue(ChannelBindingMessageProperty.Name, out value))
{
property = value as ChannelBindingMessageProperty;
return property != null;
}
return false;
}
public void AddTo(Message message)
{
if (message == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message");
}
AddTo(message.Properties);
}
public void AddTo(MessageProperties properties)
{
ThrowIfDisposed();
if (properties == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("properties");
}
properties.Add(ChannelBindingMessageProperty.Name, this);
}
public IMessageProperty CreateCopy()
{
lock (_thisLock)
{
ThrowIfDisposed();
_refCount++;
return this;
}
}
public void Dispose()
{
if (!this.IsDisposed)
{
lock (_thisLock)
{
if (!this.IsDisposed && --_refCount == 0)
{
if (_ownsCleanup)
{
// Accessing via IDisposable to avoid Security check (functionally the same)
((IDisposable)_channelBinding).Dispose();
}
}
}
}
}
private void ThrowIfDisposed()
{
if (this.IsDisposed)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ObjectDisposedException(this.GetType().FullName));
}
}
}
}
|