| File: System\ServiceModel\Description\OperationDescription.cs | Web Access |
| Project: src\src\System.ServiceModel.Primitives\src\System.ServiceModel.Primitives.csproj (System.ServiceModel.Primitives) |
// 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.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Reflection; namespace System.ServiceModel.Description { [DebuggerDisplay("Name={XmlName}, IsInitiating={IsInitiating}, IsTerminating={IsTerminating}")] public class OperationDescription { internal const string SessionOpenedAction = "http://schemas.microsoft.com/2011/02/session/onopen"; // Copied from WebSocketTransportSettings.ConnectionOpenedAction; private bool _isSessionOpenNotificationEnabled; private ContractDescription _declaringContract; private MethodInfo _taskMethod; private bool _hasNoDisposableParameters; public OperationDescription(string name, ContractDescription declaringContract) { if (name == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(name)); } if (name.Length == 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new ArgumentOutOfRangeException(nameof(name), SRP.SFxOperationDescriptionNameCannotBeEmpty)); } XmlName = new XmlName(name, true /*isEncoded*/); _declaringContract = declaringContract ?? throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(declaringContract)); IsInitiating = true; IsTerminating = false; Faults = new FaultDescriptionCollection(); Messages = new MessageDescriptionCollection(); Behaviors = new KeyedByTypeCollection<IOperationBehavior>(); KnownTypes = new Collection<Type>(); } internal OperationDescription(string name, ContractDescription declaringContract, bool validateRpcWrapperName) : this(name, declaringContract) { IsValidateRpcWrapperName = validateRpcWrapperName; } public KeyedCollection<Type, IOperationBehavior> OperationBehaviors { get { return Behaviors; } } [EditorBrowsable(EditorBrowsableState.Never)] public KeyedByTypeCollection<IOperationBehavior> Behaviors { get; } // Not serializable on purpose, metadata import/export cannot // produce it, only available when binding to runtime public MethodInfo TaskMethod { get { return _taskMethod; } set { _taskMethod = value; } } // Not serializable on purpose, metadata import/export cannot // produce it, only available when binding to runtime public MethodInfo SyncMethod { get; set; } // Not serializable on purpose, metadata import/export cannot // produce it, only available when binding to runtime public MethodInfo BeginMethod { get; set; } internal MethodInfo OperationMethod { get { if (SyncMethod == null) { return TaskMethod ?? BeginMethod; } else { return SyncMethod; } } } internal bool HasNoDisposableParameters { get { return _hasNoDisposableParameters; } set { _hasNoDisposableParameters = value; } } // Not serializable on purpose, metadata import/export cannot // produce it, only available when binding to runtime public MethodInfo EndMethod { get; set; } public ContractDescription DeclaringContract { get { return _declaringContract; } set { if (value == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(DeclaringContract)); } else { _declaringContract = value; } } } public FaultDescriptionCollection Faults { get; } public bool IsOneWay { get { return Messages.Count == 1; } } public bool IsInitiating { get; set; } internal bool IsServerInitiated() { EnsureInvariants(); return Messages[0].Direction == MessageDirection.Output; } public bool IsTerminating { get; set; } public Collection<Type> KnownTypes { get; } // Messages[0] is the 'request' (first of MEP), and for non-oneway MEPs, Messages[1] is the 'response' (second of MEP) public MessageDescriptionCollection Messages { get; } internal XmlName XmlName { get; } internal string CodeName { get { return XmlName.DecodedName; } } public string Name { get { return XmlName.EncodedName; } } internal bool IsValidateRpcWrapperName { get; } = true; internal Type TaskTResult { get; set; } internal bool HasOutputParameters { get { // For non-oneway operations, Messages[1] is the 'response' return (Messages.Count > 1) && (Messages[1].Body.Parts.Count > 0); } } internal bool IsSessionOpenNotificationEnabled { get { return _isSessionOpenNotificationEnabled; } set { _isSessionOpenNotificationEnabled = value; } } internal void EnsureInvariants() { if (Messages.Count != 1 && Messages.Count != 2) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SRP.Format(SRP.SFxOperationMustHaveOneOrTwoMessages, Name))); } } } }