internal static LogicalChannel Register(Activity activity, ChannelToken endpoint, Type contractType) { if (activity == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("activity"); } if (endpoint == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("endpoint"); } if (contractType == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("contractType"); } LogicalChannel logicalChannel = GetLogicalChannel(activity, endpoint, contractType); if (logicalChannel == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.Error_FailedToRegisterChannel, endpoint.Name))); } return(logicalChannel); }
public static void SetContext(Activity activity, string endpointName, string ownerActivityName, Type contractType, IDictionary <string, string> context) { if (activity == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("activity"); } if (string.IsNullOrEmpty(endpointName)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("endpointName", SR2.GetString(SR2.Error_ArgumentValueNullOrEmptyString)); } if (contractType == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("contractType"); } LogicalChannel logicalChannel = ChannelToken.GetLogicalChannel(activity, endpointName, ownerActivityName, contractType); if (logicalChannel != null) { if (context != null) { logicalChannel.Context = context; } else { logicalChannel.Context = ContextMessageProperty.Empty.Context; } } }
protected internal override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext) { TypedOperationInfo serviceOperationInfo = this.ServiceOperationInfo; if (serviceOperationInfo == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.Error_ServiceOperationInfoNotSpecified, this.Name))); } MethodInfo methodInfo = serviceOperationInfo.GetMethodInfo(executionContext); if (methodInfo == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.Error_MethodInfoNotAvailable, this.Name))); } ChannelToken channelToken = this.ChannelToken; LogicalChannel logicalChannel = ChannelToken.Register(this, channelToken, serviceOperationInfo.ContractType); if (!logicalChannel.Initialized) { logicalChannel.Initialize(channelToken.EndpointName, this.CustomAddress); } using (ChannelManagerService.ChannelTicket leasedChannel = ChannelManagerService.Take(executionContext, this.WorkflowInstanceId, logicalChannel)) { using (OperationContextScope scope = new OperationContextScope((IContextChannel)leasedChannel.Channel)) { EventHandler <SendActivityEventArgs>[] invocationList = this.GetInvocationList <EventHandler <SendActivityEventArgs> >(SendActivity.BeforeSendEvent); if (invocationList != null && invocationList.Length > 0) { base.RaiseGenericEvent(SendActivity.BeforeSendEvent, this, new SendActivityEventArgs(this)); } SendOperationInfoHelper helper = this.OperationHelper; WorkflowParameterBindingCollection bindings = this.ParameterBindings; object[] parameters = helper.GetInputs(this, bindings); object returnValue = null; bool isSessionless = ChannelManagerHelpers.IsSessionlessContract(logicalChannel.ContractType); bool hasContext = (logicalChannel.Context != null && logicalChannel.Context.Count > 0); bool fatalException = false; if (!isSessionless && hasContext) { ChannelManagerService.ApplyLogicalChannelContext(logicalChannel); } try { returnValue = this.InvokeOperation(methodInfo, leasedChannel.Channel, parameters); } catch (Exception exception) { if (Fx.IsFatal(exception)) { fatalException = true; } throw; } finally { if (!fatalException && !hasContext && !isSessionless && !helper.IsOneWay) { ChannelManagerService.UpdateLogicalChannelContext(logicalChannel); } } helper.PopulateOutputs(this, bindings, parameters, returnValue); invocationList = this.GetInvocationList <EventHandler <SendActivityEventArgs> >(SendActivity.AfterResponseEvent); if (invocationList != null && invocationList.Length > 0) { base.RaiseGenericEvent(SendActivity.AfterResponseEvent, this, new SendActivityEventArgs(this)); } } } return(ActivityExecutionStatus.Closed); }
internal PooledChannelTicket TakeChannel(Guid workflowId, LogicalChannel logicalChannel) { if (this.closed) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.Error_CannotProvideChannel_ServiceStopped, logicalChannel.ConfigurationName, logicalChannel.CustomAddress))); } if (workflowId == Guid.Empty) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("workflowId", SR2.GetString(SR2.Error_Cache_InvalidWorkflowId)); } if (logicalChannel == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("logicalChannel"); } WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "ChannelManagerService: get channel for workflow instance {0}, logical channel {1}", new object[] { workflowId, logicalChannel.InstanceId }); string endpointName = logicalChannel.ConfigurationName; Type contractType = logicalChannel.ContractType; string customAddress = logicalChannel.CustomAddress; ChannelPoolKey channelKey; ChannelManager.PooledChannel channel = this.channelManager.TakeChannel(endpointName, contractType, customAddress, out channelKey); if (channel == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.Error_CannotProvideChannel, logicalChannel.ConfigurationName, logicalChannel.CustomAddress))); } PooledChannelTicket pooledChannel = new PooledChannelTicket(this, channel, channelKey, workflowId, logicalChannel.InstanceId); return pooledChannel; }
internal static void UpdateLogicalChannelContext(LogicalChannel logicalChannel) { Fx.Assert(OperationContext.Current != null, "Can be called from valid OperationContextScope"); WorkflowTrace.Host.TraceEvent(TraceEventType.Verbose, 0, "ChannelManagerService: updating context associated with logical channel {0}", logicalChannel.InstanceId); ContextMessageProperty contextMessageProperty; MessageProperties properties = OperationContext.Current.IncomingMessageProperties; if (properties != null && ContextMessageProperty.TryGet(properties, out contextMessageProperty)) { logicalChannel.Context = contextMessageProperty.Context; } }
internal static ChannelTicket Take(ActivityExecutionContext executionContext, Guid workflowId, LogicalChannel logicalChannel) { if (executionContext == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("executionContext"); } if (workflowId == Guid.Empty) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("workflowId", SR2.GetString(SR2.Error_Cache_InvalidWorkflowId)); } if (logicalChannel == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("logicalChannel"); } ChannelManagerService channelManager = executionContext.GetService<ChannelManagerService>(); ChannelTicket channel; if (channelManager != null) { channel = channelManager.TakeChannel(workflowId, logicalChannel); } else { channel = ChannelManagerService.CreateTransientChannel(logicalChannel); } return channel; }
internal static TransientChannelTicket CreateTransientChannel(LogicalChannel logicalChannel) { DiagnosticUtility.DebugAssert(logicalChannel != null, "logical channel cannot be null"); ChannelFactory factory = null; IChannel channel = null; bool channelOpened = false; try { factory = ChannelManagerHelpers.CreateChannelFactory(logicalChannel.ConfigurationName, logicalChannel.ContractType); channel = ChannelManagerHelpers.CreateChannel(logicalChannel.ContractType, factory, logicalChannel.CustomAddress); channelOpened = true; } finally { if (!channelOpened) { if (channel != null) { ChannelManagerHelpers.CloseCommunicationObject(channel); } if (factory != null) { ChannelManagerHelpers.CloseCommunicationObject(factory); } } } return new TransientChannelTicket(channel, factory); }
internal static void ApplyLogicalChannelContext(LogicalChannel logicalChannel) { Fx.Assert(OperationContext.Current != null, "Can be called within a valid OperationContext Scope"); WorkflowTrace.Host.TraceEvent(TraceEventType.Verbose, 0, "ChannelManagerService: updating context associated with logical channel {0}", logicalChannel.InstanceId); if (logicalChannel.Context != null) { new ContextMessageProperty(logicalChannel.Context).AddOrReplaceInMessageProperties(OperationContext.Current.OutgoingMessageProperties); } }
internal static LogicalChannel GetLogicalChannel(Activity activity, string name, string ownerActivityName, Type contractType) { if (activity == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("activity"); } if (string.IsNullOrEmpty(name)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("name", SR2.GetString(SR2.Error_ArgumentValueNullOrEmptyString)); } if (contractType == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("contractType"); } Activity contextActivity = activity.ContextActivity; Activity owner = null; if (contextActivity == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.Error_ContextOwnerActivityMissing))); } if (string.IsNullOrEmpty(ownerActivityName)) { owner = contextActivity.RootActivity; } else { while (contextActivity != null) { owner = contextActivity.GetActivityByName(ownerActivityName, true); if (owner != null) { break; } contextActivity = contextActivity.Parent; if (contextActivity != null) { contextActivity = contextActivity.ContextActivity; } } } if (owner == null && !string.IsNullOrEmpty(ownerActivityName)) { owner = Helpers.ParseActivityForBind(activity, ownerActivityName); } if (owner == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.Error_ContextOwnerActivityMissing))); } LogicalChannel logicalChannel = null; LogicalChannelCollection collection = owner.GetValue(LogicalChannelCollection.LogicalChannelCollectionProperty) as LogicalChannelCollection; if (collection == null) { collection = new LogicalChannelCollection(); owner.SetValue(LogicalChannelCollection.LogicalChannelCollectionProperty, collection); logicalChannel = new LogicalChannel(name, contractType); collection.Add(logicalChannel); } else if (!collection.Contains(name)) { logicalChannel = new LogicalChannel(name, contractType); collection.Add(logicalChannel); } else { logicalChannel = collection[name]; } if (logicalChannel.ContractType != contractType) { logicalChannel = null; } return logicalChannel; }
internal static LogicalChannel GetLogicalChannel(Activity activity, string name, string ownerActivityName, Type contractType) { if (activity == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("activity"); } if (string.IsNullOrEmpty(name)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("name", SR2.GetString(SR2.Error_ArgumentValueNullOrEmptyString)); } if (contractType == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("contractType"); } Activity contextActivity = activity.ContextActivity; Activity owner = null; if (contextActivity == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.Error_ContextOwnerActivityMissing))); } if (string.IsNullOrEmpty(ownerActivityName)) { owner = contextActivity.RootActivity; } else { while (contextActivity != null) { owner = contextActivity.GetActivityByName(ownerActivityName, true); if (owner != null) { break; } contextActivity = contextActivity.Parent; if (contextActivity != null) { contextActivity = contextActivity.ContextActivity; } } } if (owner == null && !string.IsNullOrEmpty(ownerActivityName)) { owner = Helpers.ParseActivityForBind(activity, ownerActivityName); } if (owner == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.Error_ContextOwnerActivityMissing))); } LogicalChannel logicalChannel = null; LogicalChannelCollection collection = owner.GetValue(LogicalChannelCollection.LogicalChannelCollectionProperty) as LogicalChannelCollection; if (collection == null) { collection = new LogicalChannelCollection(); owner.SetValue(LogicalChannelCollection.LogicalChannelCollectionProperty, collection); logicalChannel = new LogicalChannel(name, contractType); collection.Add(logicalChannel); } else if (!collection.Contains(name)) { logicalChannel = new LogicalChannel(name, contractType); collection.Add(logicalChannel); } else { logicalChannel = collection[name]; } if (logicalChannel.ContractType != contractType) { logicalChannel = null; } return(logicalChannel); }