| File: System\ServiceModel\Channels\TransactionChannelFactory.cs | Web Access |
| Project: ..\..\..\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.ServiceModel.Description; using System.ServiceModel.Security; namespace System.ServiceModel.Channels { internal sealed class TransactionChannelFactory<TChannel> : LayeredChannelFactory<TChannel>, ITransactionChannelManager { private SecurityStandardsManager _standardsManager; private Dictionary<DirectionalAction, TransactionFlowOption> _dictionary; private TransactionProtocol _transactionProtocol; private bool _allowWildcardAction; public TransactionChannelFactory( TransactionProtocol transactionProtocol, BindingContext context, Dictionary<DirectionalAction, TransactionFlowOption> dictionary, bool allowWildcardAction) : base(context.Binding, context.BuildInnerChannelFactory<TChannel>()) { _dictionary = dictionary; TransactionProtocol = transactionProtocol; _allowWildcardAction = allowWildcardAction; _standardsManager = SecurityStandardsHelper.CreateStandardsManager(TransactionProtocol); } public TransactionProtocol TransactionProtocol { get { return _transactionProtocol; } set { if (!TransactionProtocol.IsDefined(value)) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new ArgumentException(SRP.SFxBadTransactionProtocols)); _transactionProtocol = value; } } public TransactionFlowOption FlowIssuedTokens { get; set; } public SecurityStandardsManager StandardsManager { get { return _standardsManager; } set { _standardsManager = value ?? SecurityStandardsHelper.CreateStandardsManager(_transactionProtocol); } } public IDictionary<DirectionalAction, TransactionFlowOption> Dictionary => _dictionary; public TransactionFlowOption GetTransaction(MessageDirection direction, string action) { TransactionFlowOption txOption; if (!_dictionary.TryGetValue(new DirectionalAction(direction, action), out txOption)) { if (_allowWildcardAction && _dictionary.TryGetValue(new DirectionalAction(direction, MessageHeaders.WildcardAction), out txOption)) { return txOption; } else { return TransactionFlowOption.NotAllowed; } } else { return txOption; } } protected override TChannel OnCreateChannel(EndpointAddress remoteAddress, Uri via) { TChannel innerChannel = ((IChannelFactory<TChannel>)InnerChannelFactory).CreateChannel(remoteAddress, via); return CreateTransactionChannel(innerChannel); } private TChannel CreateTransactionChannel(TChannel innerChannel) { if (typeof(TChannel) == typeof(IDuplexSessionChannel)) { return (TChannel)(object)new TransactionDuplexSessionChannel(this, (IDuplexSessionChannel)(object)innerChannel); } else if (typeof(TChannel) == typeof(IRequestSessionChannel)) { return (TChannel)(object)new TransactionRequestSessionChannel(this, (IRequestSessionChannel)(object)innerChannel); } else if (typeof(TChannel) == typeof(IOutputSessionChannel)) { return (TChannel)(object)new TransactionOutputSessionChannel(this, (IOutputSessionChannel)(object)innerChannel); } else if (typeof(TChannel) == typeof(IOutputChannel)) { return (TChannel)(object)new TransactionOutputChannel(this, (IOutputChannel)(object)innerChannel); } else if (typeof(TChannel) == typeof(IRequestChannel)) { return (TChannel)(object)new TransactionRequestChannel(this, (IRequestChannel)(object)innerChannel); } else if (typeof(TChannel) == typeof(IDuplexChannel)) { return (TChannel)(object)new TransactionDuplexChannel(this, (IDuplexChannel)(object)innerChannel); } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( CreateChannelTypeNotSupportedException(typeof(TChannel))); } } private sealed class TransactionOutputChannel : TransactionOutputChannelGeneric<IOutputChannel> { public TransactionOutputChannel(ChannelManagerBase channelManager, IOutputChannel innerChannel) : base(channelManager, innerChannel) { } } private sealed class TransactionRequestChannel : TransactionRequestChannelGeneric<IRequestChannel> { public TransactionRequestChannel(ChannelManagerBase channelManager, IRequestChannel innerChannel) : base(channelManager, innerChannel) { } } private sealed class TransactionDuplexChannel : TransactionOutputDuplexChannelGeneric<IDuplexChannel> { public TransactionDuplexChannel(ChannelManagerBase channelManager, IDuplexChannel innerChannel) : base(channelManager, innerChannel) { } } private sealed class TransactionOutputSessionChannel : TransactionOutputChannelGeneric<IOutputSessionChannel>, IOutputSessionChannel { public TransactionOutputSessionChannel(ChannelManagerBase channelManager, IOutputSessionChannel innerChannel) : base(channelManager, innerChannel) { } public IOutputSession Session => InnerChannel.Session; } private sealed class TransactionRequestSessionChannel : TransactionRequestChannelGeneric<IRequestSessionChannel>, IRequestSessionChannel { public TransactionRequestSessionChannel(ChannelManagerBase channelManager, IRequestSessionChannel innerChannel) : base(channelManager, innerChannel) { } public IOutputSession Session => InnerChannel.Session; } private sealed class TransactionDuplexSessionChannel : TransactionOutputDuplexChannelGeneric<IDuplexSessionChannel>, IDuplexSessionChannel { public TransactionDuplexSessionChannel(ChannelManagerBase channelManager, IDuplexSessionChannel innerChannel) : base(channelManager, innerChannel) { } public IDuplexSession Session => InnerChannel.Session; } } internal static class SecurityStandardsHelper { private static readonly SecurityStandardsManager s_securityStandardsManager2007 = CreateStandardsManager(MessageSecurityVersion.WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12); private static SecurityStandardsManager CreateStandardsManager(MessageSecurityVersion securityVersion) { return new SecurityStandardsManager( securityVersion, new WSSecurityTokenSerializer(securityVersion.SecurityVersion, securityVersion.TrustVersion, securityVersion.SecureConversationVersion, false, null, null, null)); } public static SecurityStandardsManager CreateStandardsManager(TransactionProtocol transactionProtocol) { if (transactionProtocol == TransactionProtocol.WSAtomicTransactionOctober2004 || transactionProtocol == TransactionProtocol.OleTransactions) { return SecurityStandardsManager.DefaultInstance; } else { return s_securityStandardsManager2007; } } } }