Imported Upstream version 4.0.0~alpha1

Former-commit-id: 806294f5ded97629b74c85c09952f2a74fe182d9
This commit is contained in:
Jo Shields
2015-04-07 09:35:12 +01:00
parent 283343f570
commit 3c1f479b9d
22469 changed files with 2931443 additions and 869343 deletions

View File

@@ -0,0 +1,463 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
#region Using directives
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Runtime.Serialization;
using System.Workflow.ComponentModel;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Messaging;
using System.Workflow.Runtime;
using System.Xml;
#endregion
namespace System.Workflow.Activities
{
internal static class CorrelationResolver
{
static Dictionary<Type, CorrelationMethodResolver> cachedTypeResolver = new Dictionary<Type, CorrelationMethodResolver>();
static object mutex = new object();
internal static bool IsInitializingMember(Type interfaceType, string memberName, object[] methodArgs)
{
if (interfaceType == null)
throw new ArgumentNullException("interfaceType");
if (memberName == null)
throw new ArgumentNullException("memberName");
if (memberName.Length == 0)
throw new ArgumentException(SR.GetString(SR.Error_EventNameMissing));
ICorrelationProvider correlationProvider = CorrelationResolver.GetCorrelationProvider(interfaceType);
return correlationProvider.IsInitializingMember(interfaceType, memberName, methodArgs);
}
internal static ICollection<CorrelationProperty> ResolveCorrelationValues(Type interfaceType, string eventName, object[] eventArgs, bool provideInitializerTokens)
{
if (interfaceType == null)
throw new ArgumentNullException("interfaceType");
if (eventName == null)
throw new ArgumentNullException("eventName");
if (eventName.Length == 0)
throw new ArgumentException(SR.GetString(SR.Error_EventNameMissing));
ICorrelationProvider correlationProvider = CorrelationResolver.GetCorrelationProvider(interfaceType);
return correlationProvider.ResolveCorrelationPropertyValues(interfaceType, eventName, eventArgs, provideInitializerTokens);
}
internal static ICorrelationProvider GetCorrelationProvider(Type interfaceType)
{
CorrelationMethodResolver resolver = GetResolver(interfaceType);
return resolver.CorrelationProvider;
}
private static CorrelationMethodResolver GetResolver(Type interfaceType)
{
CorrelationMethodResolver resolver = null;
cachedTypeResolver.TryGetValue(interfaceType, out resolver);
if (resolver == null)
{
lock (mutex)
{
cachedTypeResolver.TryGetValue(interfaceType, out resolver);
if (resolver == null)
{
resolver = new CorrelationMethodResolver(interfaceType);
cachedTypeResolver.Add(interfaceType, resolver);
}
}
}
return resolver;
}
}
internal sealed class CorrelationMethodResolver
{
Type interfaceType;
// a correlation provider for each interface type
ICorrelationProvider correlationProvider;
object corrProviderSync = new object();
internal CorrelationMethodResolver(Type interfaceType)
{
this.interfaceType = interfaceType;
}
internal ICorrelationProvider CorrelationProvider
{
get
{
if (this.correlationProvider == null)
{
lock (this.corrProviderSync)
{
if (this.correlationProvider == null)
{
ICorrelationProvider provider = null;
object[] corrProviderAttribs = this.interfaceType.GetCustomAttributes(typeof(CorrelationProviderAttribute), true);
if (corrProviderAttribs.Length == 0)
{
corrProviderAttribs = this.interfaceType.GetCustomAttributes(typeof(ExternalDataExchangeAttribute), true);
object[] corrParameterAttribs = this.interfaceType.GetCustomAttributes(typeof(CorrelationParameterAttribute), true);
if (corrProviderAttribs.Length != 0 && corrParameterAttribs.Length != 0)
{
// no provider specified but it is a data exchange correlation service
// hence use our default correlation
provider = new DefaultCorrelationProvider(this.interfaceType);
}
else
{
// opaque interface with no correlation
provider = new NonCorrelatedProvider();
}
}
else
{
CorrelationProviderAttribute cpattrib = corrProviderAttribs[0] as CorrelationProviderAttribute;
Type providerType = cpattrib.CorrelationProviderType;
provider = Activator.CreateInstance(providerType) as ICorrelationProvider;
}
System.Threading.Thread.MemoryBarrier();
this.correlationProvider = provider;
}
}
}
return this.correlationProvider;
}
}
}
internal sealed class CorrelationPropertyValue
{
string name;
string locationPath;
int signaturePosition;
internal CorrelationPropertyValue(string name, string locationPath, int signaturePosition)
{
this.name = name;
this.locationPath = locationPath;
this.signaturePosition = signaturePosition;
}
internal object GetValue(object[] args)
{
if (args.Length <= this.signaturePosition)
throw new ArgumentOutOfRangeException("args");
object arg = args[this.signaturePosition];
if (arg == null)
return arg;
Type type = arg.GetType();
object val = arg;
if (this.locationPath.Length != 0)
{
string[] split = locationPath.Split(new Char[] { '.' });
for (int i = 1; i < split.Length; i++)
{
string s = split[i];
if (null == arg)
break;
val = type.InvokeMember(s, BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetField | BindingFlags.GetProperty, null, arg, null, null);
MemberInfo[] mInfos = type.GetMember(s, BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetField | BindingFlags.GetProperty);
type = GetMemberType(mInfos[0]);
arg = val;
}
}
return val;
}
internal string Name
{
get
{
return this.name;
}
}
private Type GetMemberType(MemberInfo mInfo)
{
Type type = null;
switch (mInfo.MemberType)
{
case MemberTypes.Field:
type = ((FieldInfo)mInfo).FieldType;
break;
case MemberTypes.Property:
type = ((PropertyInfo)mInfo).PropertyType;
break;
default:
Debug.Assert(false, "locationPath points to something other than a Field/Property");
return null;
}
return type;
}
}
internal sealed class DefaultCorrelationProvider : ICorrelationProvider
{
Type interfaceType;
// map of method name to correlation properties
Dictionary<string, CorrelationPropertyValue[]> cachedCorrelationProperties;
object cachedCorrelationPropertiesSync = new object();
// cached initializers
// map operation to bool flag to indicate events
Dictionary<string, bool> initializerCorrelationPropertys = null;
object initializerCorrelationPropertysSync = new object();
internal DefaultCorrelationProvider(Type interfaceType)
{
this.cachedCorrelationProperties = new Dictionary<string, CorrelationPropertyValue[]>();
this.interfaceType = interfaceType;
}
ICollection<CorrelationProperty> ICorrelationProvider.ResolveCorrelationPropertyValues(Type interfaceType, string methodName, object[] methodArgs, bool provideInitializerTokens)
{
CorrelationPropertyValue[] correlationProperties = null;
if (methodArgs == null || provideInitializerTokens)
{
return null; // no initializer specific token to return
}
this.cachedCorrelationProperties.TryGetValue(methodName, out correlationProperties);
if (correlationProperties == null)
{
lock (this.cachedCorrelationPropertiesSync)
{
this.cachedCorrelationProperties.TryGetValue(methodName, out correlationProperties);
if (correlationProperties == null)
{
correlationProperties = GetCorrelationProperties(interfaceType, methodName);
this.cachedCorrelationProperties.Add(methodName, correlationProperties);
}
}
}
List<CorrelationProperty> predicates = new List<CorrelationProperty>();
for (int i = 0; i < correlationProperties.Length; i++)
{
predicates.Add(new CorrelationProperty(correlationProperties[i].Name, correlationProperties[i].GetValue(methodArgs)));
}
return predicates;
}
private Dictionary<string, bool> InitializerCorrelationPropertys
{
get
{
if (this.initializerCorrelationPropertys == null)
{
lock (this.initializerCorrelationPropertysSync)
{
if (this.initializerCorrelationPropertys == null)
{
Dictionary<string, bool> members = new Dictionary<string, bool>();
// note this is separated out since we may need to distinguish between events & methods
foreach (EventInfo member in this.interfaceType.GetEvents())
{
if ((member.GetCustomAttributes(typeof(CorrelationInitializerAttribute), true)).Length > 0)
{
members.Add(member.Name, true);
}
}
foreach (MethodInfo member in this.interfaceType.GetMethods())
{
if ((member.GetCustomAttributes(typeof(CorrelationInitializerAttribute), true)).Length > 0)
{
members.Add(member.Name, false);
}
}
this.initializerCorrelationPropertys = members;
}
}
}
return this.initializerCorrelationPropertys;
}
}
bool ICorrelationProvider.IsInitializingMember(Type interfaceType, string memberName, object[] methodArgs)
{
return InitializerCorrelationPropertys.ContainsKey(memberName);
}
private CorrelationPropertyValue[] GetCorrelationProperties(Type interfaceType, string methodName)
{
CorrelationPropertyValue[] correlationProperties = null;
if (interfaceType.GetCustomAttributes(typeof(ExternalDataExchangeAttribute), true).Length == 0)
throw new InvalidOperationException(SR.GetString(SR.Error_ExternalDataExchangeException, interfaceType.AssemblyQualifiedName));
List<Object> correlationParamAttributes = new List<Object>();
correlationParamAttributes.AddRange(GetCorrelationParameterAttributes(interfaceType));
if (correlationParamAttributes.Count == 0)
throw new InvalidOperationException(SR.GetString(SR.Error_CorrelationParameterException, interfaceType.AssemblyQualifiedName));
correlationProperties = new CorrelationPropertyValue[correlationParamAttributes.Count];
Dictionary<String, CorrelationAliasAttribute> corrAliases = null;
MethodInfo methodInfo = null;
GetMethodInfo(interfaceType, methodName, out methodInfo, out corrAliases);
if (methodInfo == null)
{
throw new MissingMethodException(interfaceType.AssemblyQualifiedName, methodName);
}
ParameterInfo[] parameters = methodInfo.GetParameters();
int i = 0;
foreach (CorrelationParameterAttribute paramAttribute in correlationParamAttributes)
{
String location = paramAttribute.Name;
CorrelationAliasAttribute aliasAttribute = GetMatchingCorrelationAlias(paramAttribute, corrAliases, correlationParamAttributes.Count == 1);
if (aliasAttribute != null)
location = aliasAttribute.Path;
CorrelationPropertyValue value = GetCorrelationProperty(parameters, paramAttribute.Name, location);
if (value == null)
throw new InvalidOperationException(SR.GetString(SR.Error_CorrelationParameterException, interfaceType.AssemblyQualifiedName, paramAttribute.Name, methodName));
correlationProperties[i++] = value;
}
return correlationProperties;
}
private CorrelationAliasAttribute GetMatchingCorrelationAlias(CorrelationParameterAttribute paramAttribute, Dictionary<String, CorrelationAliasAttribute> correlationAliases, bool defaultParameter)
{
CorrelationAliasAttribute corrAlias = null;
if (correlationAliases == null) return null;
if (defaultParameter)
{
if (correlationAliases.TryGetValue("", out corrAlias))
{
return corrAlias;
}
}
correlationAliases.TryGetValue(paramAttribute.Name, out corrAlias);
return corrAlias;
}
private CorrelationPropertyValue GetCorrelationProperty(ParameterInfo[] parameters, String propertyName, String location)
{
string[] split = location.Split(new Char[] { '.' });
if (split.Length == 1 && parameters.Length == 2)
{
if (typeof(ExternalDataEventArgs).IsAssignableFrom(parameters[1].ParameterType))
{
string aliasedLocation = "e." + location;
return GetCorrelationProperty(parameters, propertyName, "e", aliasedLocation);
}
}
string parameterName = split[0];
return GetCorrelationProperty(parameters, propertyName, parameterName, location);
}
private void GetMethodInfo(Type interfaceType, string methodName, out MethodInfo methodInfo, out Dictionary<String, CorrelationAliasAttribute> correlationAliases)
{
correlationAliases = new Dictionary<String, CorrelationAliasAttribute>();
Object[] customAttrs = null;
methodInfo = null;
// check events
BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
EventInfo eventInfo = interfaceType.GetEvent(methodName, bindingFlags);
if (eventInfo != null)
{
customAttrs = eventInfo.GetCustomAttributes(typeof(CorrelationAliasAttribute), true);
if (customAttrs == null || customAttrs.Length == 0)
{
customAttrs = eventInfo.EventHandlerType.GetCustomAttributes(typeof(CorrelationAliasAttribute), true);
}
MethodInfo[] methInfo = eventInfo.EventHandlerType.GetMethods();
methodInfo = methInfo[0];
}
else
{
// check methods
methodInfo = interfaceType.GetMethod(methodName, bindingFlags);
if (methodInfo == null)
{
throw new MissingMethodException(interfaceType.AssemblyQualifiedName, methodName);
}
customAttrs = methodInfo.GetCustomAttributes(typeof(CorrelationAliasAttribute), true);
}
foreach (CorrelationAliasAttribute aliasAttribute in customAttrs)
{
if (customAttrs.Length > 1)
{
Debug.Assert(aliasAttribute.Name != null);
if (aliasAttribute.Name == null)
throw new ArgumentNullException("ParameterName");
}
correlationAliases.Add(aliasAttribute.Name == null ? "" : aliasAttribute.Name, aliasAttribute);
}
}
private CorrelationPropertyValue GetCorrelationProperty(ParameterInfo[] parameters, string propertyName, string parameterName, string location)
{
for (int j = 0; parameters != null && j < parameters.Length; j++)
{
ParameterInfo param = parameters[j];
if (param.Name == parameterName)
{
// parameter match
return new CorrelationPropertyValue(propertyName, location, param.Position);
}
}
return null;
}
private object[] GetCorrelationParameterAttributes(Type type)
{
return type.GetCustomAttributes(typeof(CorrelationParameterAttribute), true);
}
}
internal sealed class NonCorrelatedProvider : ICorrelationProvider
{
internal NonCorrelatedProvider()
{
}
ICollection<CorrelationProperty> ICorrelationProvider.ResolveCorrelationPropertyValues(Type interfaceType, string methodName, object[] methodArgs, bool provideInitializerTokens)
{
// non correlated
// no values to return
return null;
}
bool ICorrelationProvider.IsInitializingMember(Type interfaceType, string memberName, object[] methodArgs)
{
return true;
}
}
}

View File

@@ -0,0 +1,308 @@
#region Using directives
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Collections;
using System.Reflection;
using System.Runtime.Serialization;
using System.Workflow.ComponentModel;
using System.Workflow.Runtime;
using System.Workflow.Runtime.Hosting;
using System.Runtime.Remoting.Messaging;
using System.Xml;
using System.Globalization;
#endregion
namespace System.Workflow.Activities
{
internal interface ICorrelationProvider
{
ICollection<CorrelationProperty> ResolveCorrelationPropertyValues(Type interfaceType, string memberName, object[] methodArgs, bool provideInitializerTokens);
bool IsInitializingMember(Type interfaceType, string memberName, object[] methodArgs);
}
[AttributeUsageAttribute(AttributeTargets.Interface | AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
internal sealed class CorrelationProviderAttribute : Attribute
{
private Type correlationProviderType;
internal CorrelationProviderAttribute(Type correlationProviderType)
{
this.correlationProviderType = correlationProviderType;
}
internal Type CorrelationProviderType
{
get
{
return this.correlationProviderType;
}
}
}
internal static class CorrelationService
{
internal static void Initialize(IServiceProvider context, Activity activity, Type interfaceType, string methodName, Guid instanceId)
{
if (activity == null)
throw new ArgumentNullException("activity");
if (interfaceType == null)
throw new ArgumentNullException("interfaceType");
if (methodName == null)
throw new ArgumentNullException("methodName");
Subscribe(context, activity, interfaceType, methodName, null, instanceId);
InitializeFollowers(context, interfaceType, methodName);
}
internal static bool Subscribe(IServiceProvider context, Activity activity, Type interfaceType, string methodName, IActivityEventListener<QueueEventArgs> eventListener, Guid instanceId)
{
if (activity == null)
throw new ArgumentNullException("activity");
if (interfaceType == null)
throw new ArgumentNullException("interfaceType");
if (methodName == null)
throw new ArgumentNullException("methodName");
WorkflowQueuingService queueService = (WorkflowQueuingService)context.GetService(typeof(WorkflowQueuingService));
IComparable queueName = ResolveQueueName(activity, interfaceType, methodName);
if (queueName != null)
{
// initializer
WorkflowQueue queue = null;
if (queueService.Exists(queueName))
{
queue = queueService.GetWorkflowQueue(queueName);
queue.Enabled = true;
}
else
{
queue = queueService.CreateWorkflowQueue(queueName, true);
}
if (eventListener != null)
{
queue.RegisterForQueueItemAvailable(eventListener, activity.QualifiedName);
WorkflowActivityTrace.Activity.TraceEvent(TraceEventType.Information, 0, "CorrelationService: activity '{0}' subscribing to QueueItemAvailable", activity.QualifiedName);
return true;
}
return false;
}
SubscribeForCorrelationTokenInvalidation(activity, interfaceType, methodName, eventListener, instanceId);
return false;
}
internal static bool Unsubscribe(IServiceProvider context, Activity activity, Type interfaceType, string methodName, IActivityEventListener<QueueEventArgs> eventListener)
{
if (activity == null)
throw new ArgumentException("activity");
if (interfaceType == null)
throw new ArgumentNullException("interfaceType");
if (methodName == null)
throw new ArgumentNullException("methodName");
WorkflowQueuingService queueService = (WorkflowQueuingService)context.GetService(typeof(WorkflowQueuingService));
IComparable queueName = ResolveQueueName(activity, interfaceType, methodName);
if (queueName != null)
{
if (queueService.Exists(queueName))
{
queueService.GetWorkflowQueue(queueName).UnregisterForQueueItemAvailable(eventListener);
return true;
}
}
return false;
}
internal static IComparable ResolveQueueName(Activity activity, Type interfaceType, string methodName)
{
if (activity == null)
throw new ArgumentNullException("activity");
if (interfaceType == null)
throw new ArgumentNullException("interfaceType");
if (methodName == null)
throw new ArgumentNullException("methodName");
// resolver will check for an explicit correlation provider,
// if none present this will return an uncorrelated provider.
// note, an uncorrelated methodName will always be an initializer
if (CorrelationResolver.IsInitializingMember(interfaceType, methodName, null))
{
ICollection<CorrelationProperty> corrvalues = CorrelationResolver.ResolveCorrelationValues(interfaceType, methodName, null, true);
return new EventQueueName(interfaceType, methodName, corrvalues);
}
CorrelationToken reference = GetCorrelationToken(activity);
if (!reference.Initialized)
return null;
return new EventQueueName(interfaceType, methodName, reference.Properties);
}
internal static void InvalidateCorrelationToken(Activity activity, Type interfaceType, string methodName, object[] messageArgs)
{
object correlationProvider = CorrelationResolver.GetCorrelationProvider(interfaceType);
if (correlationProvider is NonCorrelatedProvider)
return;
CorrelationToken reference = GetCorrelationToken(activity);
ICollection<CorrelationProperty> correlationvalues = CorrelationResolver.ResolveCorrelationValues(interfaceType, methodName, messageArgs, false);
if (!CorrelationResolver.IsInitializingMember(interfaceType, methodName, messageArgs))
{
if (!reference.Initialized)
throw new InvalidOperationException(SR.GetString(SR.Error_CorrelationNotInitialized, reference.Name, activity.QualifiedName));
ValidateCorrelation(reference.Properties, correlationvalues, reference.Name, activity);
return;
}
// invalidate correlation token if methodName is an initializer
reference.Initialize(activity, correlationvalues);
}
private static CorrelationToken GetCorrelationToken(Activity activity)
{
DependencyProperty dependencyProperty = DependencyProperty.FromName("CorrelationToken", activity.GetType());
if (dependencyProperty == null)
dependencyProperty = DependencyProperty.FromName("CorrelationToken", activity.GetType().BaseType);
CorrelationToken reference = activity.GetValue(dependencyProperty) as CorrelationToken;
if (reference == null)
throw new InvalidOperationException(SR.GetString(SR.Error_CorrelationTokenMissing, activity.Name));
CorrelationToken correlator = CorrelationTokenCollection.GetCorrelationToken(activity, reference.Name, reference.OwnerActivityName);
if (correlator == null)
throw new InvalidOperationException(SR.GetString(SR.Error_CorrelationTokenMissing, activity.Name));
return correlator;
}
private static void ValidateCorrelation(ICollection<CorrelationProperty> initializerProperties, ICollection<CorrelationProperty> followerProperties, string memberName, Activity activity)
{
if (followerProperties == null && initializerProperties == null)
return;
if (followerProperties == null || initializerProperties == null)
throw new InvalidOperationException(SR.GetString(SR.Error_CorrelationViolationException, memberName, activity.QualifiedName));
if (initializerProperties.Count != followerProperties.Count)
throw new InvalidOperationException(SR.GetString(SR.Error_CorrelationViolationException, memberName, activity.QualifiedName));
IEnumerator<CorrelationProperty> initializerValues = initializerProperties.GetEnumerator();
IEnumerator<CorrelationProperty> followerValues = followerProperties.GetEnumerator();
while (initializerValues.MoveNext() && followerValues.MoveNext())
{
IComparable initializerValue = initializerValues.Current.Value as IComparable;
object followerValue = followerValues.Current.Value;
// Bug DevDiv2\DevDiv 552322 - http://vstfdevdiv.redmond.corp.microsoft.com:8080/DevDiv2/DevDiv/_workitems#_a=edit&id=552322
// Reflection does not guarantee ordering, so the two collections (arrays) of
// CorrelationProperties may not be in the same order, based on Name. So we need to check all the
// elements of the followerProperties for the Name of the current initializerValue.
// The collections MIGHT be in the same order. Before searching the followerProperties collection for an element with a matching
// name, see if the current element in the initializerValues and followerValues enumerators have a matching name.
// If they do match, just fall thru because followerValue is already set to followerValues.Current.Value;
if (!initializerValues.Current.Name.Equals(followerValues.Current.Name, StringComparison.OrdinalIgnoreCase))
{
CorrelationProperty followerProperty = null;
IEnumerator<CorrelationProperty> followerEnumerator = followerProperties.GetEnumerator();
while (followerEnumerator.MoveNext())
{
// We don't need to be concerned with culture here because the names we are comparing
// are parameter names on methods in an interface.
if (initializerValues.Current.Name.Equals(followerEnumerator.Current.Name, StringComparison.OrdinalIgnoreCase))
{
// We found a matching Name in the follower collection.
// Saving the followerProperty rather than followerEnumerator.Current.Value here
// because the latter could be null and still be correct. I need something
// that indicates that we actually found a matching CorrelationProperty in the
// collection. So instead of having a separate bool, I just have a reference
// to the matching CorrelationProperty.
followerProperty = followerEnumerator.Current;
break;
}
// If we get here, the name of the parameter doesn't match, so just move to the next element in the
// followerEnumerator.
}
// If we found a followerProperty with a matching name, use it.
// In the highly, possibly impossible, event that we didn't find an element in the
// followerProperties collection with a matching name, we fall thru with
// followerValue = followerValues.Current.Value, which is exactly what the previous
// code had, and we act just like we did before.
if (followerProperty != null)
{
followerValue = followerProperty.Value;
}
}
if (initializerValue != null && (initializerValue.CompareTo(followerValue) != 0))
throw new InvalidOperationException(SR.GetString(SR.Error_CorrelationViolationException, memberName, activity.QualifiedName));
else if (initializerValues.Current.Value == null && followerValue == null)
return;
else if (initializerValue == null && followerValue != null && !followerValue.Equals(initializerValues.Current.Value))
throw new InvalidOperationException(SR.GetString(SR.Error_CorrelationViolationException, memberName, activity.QualifiedName));
}
}
private static void SubscribeForCorrelationTokenInvalidation(Activity activity, Type interfaceType, string followermethodName, IActivityEventListener<QueueEventArgs> eventListener, Guid instanceId)
{
CorrelationToken reference = GetCorrelationToken(activity);
CorrelationTokenInvalidatedHandler dataChangeEventListener = new CorrelationTokenInvalidatedHandler(interfaceType, followermethodName, eventListener, instanceId);
reference.SubscribeForCorrelationTokenInitializedEvent(activity, dataChangeEventListener);
}
private static void InitializeFollowers(IServiceProvider context, Type interfaceType, string followermethodName)
{
if (CorrelationResolver.IsInitializingMember(interfaceType, followermethodName, null))
return;
EventInfo[] events = interfaceType.GetEvents();
foreach (EventInfo e in events)
{
CreateFollowerEntry(context, interfaceType, followermethodName, e.Name);
}
}
private static void CreateFollowerEntry(IServiceProvider context, Type interfaceType, string followermethodName, string initializermethodName)
{
if (!CorrelationResolver.IsInitializingMember(interfaceType, initializermethodName, null))
return;
WorkflowQueuingService queueSvcs = (WorkflowQueuingService)context.GetService(typeof(WorkflowQueuingService));
FollowerQueueCreator follower = new FollowerQueueCreator(followermethodName);
WorkflowActivityTrace.Activity.TraceEvent(TraceEventType.Information, 0, "Creating follower {0} on initializer {1}", interfaceType.Name + followermethodName, interfaceType.Name + initializermethodName);
ICollection<CorrelationProperty> corrValues = CorrelationResolver.ResolveCorrelationValues(interfaceType, initializermethodName, null, true);
EventQueueName key = new EventQueueName(interfaceType, initializermethodName, corrValues);
WorkflowQueue initializerQueue = null;
if (queueSvcs.Exists(key))
{
initializerQueue = queueSvcs.GetWorkflowQueue(key);
}
else
{
// traversed follower before initializer
initializerQueue = queueSvcs.CreateWorkflowQueue(key, true);
initializerQueue.Enabled = false;
}
initializerQueue.RegisterForQueueItemArrived(follower);
}
internal static void UninitializeFollowers(Type interfaceType, string initializer, WorkflowQueue initializerQueue)
{
if (!CorrelationResolver.IsInitializingMember(interfaceType, initializer, null))
return;
EventInfo[] events = interfaceType.GetEvents();
foreach (EventInfo e in events)
{
string follower = e.Name;
if (!CorrelationResolver.IsInitializingMember(interfaceType, e.Name, null))
initializerQueue.UnregisterForQueueItemArrived(new FollowerQueueCreator(follower));
}
}
}
}

View File

@@ -0,0 +1,133 @@
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Collections;
using System.Reflection;
using System.Runtime.Serialization;
using System.Workflow.ComponentModel;
using System.Workflow.Runtime;
using System.Workflow.Runtime.Hosting;
namespace System.Workflow.Activities
{
[Serializable]
internal sealed class CorrelationTokenInvalidatedHandler : IActivityEventListener<CorrelationTokenEventArgs>
{
IActivityEventListener<QueueEventArgs> eventHandler;
EventQueueName queueName;
Guid subscriptionId;
Guid instanceId;
bool queueCreator;
Type interfaceType;
string followerOperation;
internal CorrelationTokenInvalidatedHandler(Type interfaceType, string operation, IActivityEventListener<QueueEventArgs> eventHandler, Guid instanceId)
{
this.eventHandler = eventHandler;
this.interfaceType = interfaceType;
this.followerOperation = operation;
this.instanceId = instanceId;
}
#region IActivityEventListener<CorrelationTokenEventArgs> Members
void IActivityEventListener<CorrelationTokenEventArgs>.OnEvent(object sender, CorrelationTokenEventArgs dataChangeEventArgs)
{
if (sender == null)
throw new ArgumentException("sender");
if (dataChangeEventArgs == null)
throw new ArgumentException("dataChangeEventArgs");
ActivityExecutionContext context = sender as ActivityExecutionContext;
Activity activity = context.Activity;
ICollection<CorrelationProperty> correlationValues = dataChangeEventArgs.CorrelationToken.Properties;
if (dataChangeEventArgs.IsInitializing)
{
CreateSubscription(this.instanceId, context, correlationValues);
return;
}
if (queueName != null)
{
if (!CorrelationResolver.IsInitializingMember(queueName.InterfaceType, queueName.MethodName,
correlationValues == null ? null : new object[] { correlationValues }))
{
DeleteSubscription(context);
}
}
dataChangeEventArgs.CorrelationToken.UnsubscribeFromCorrelationTokenInitializedEvent(activity, this);
}
#endregion
private void CreateSubscription(Guid instanceId, ActivityExecutionContext context, ICollection<CorrelationProperty> correlationValues)
{
WorkflowQueuingService queueSvcs = context.GetService<WorkflowQueuingService>();
EventQueueName queueId = new EventQueueName(this.interfaceType, this.followerOperation, correlationValues);
WorkflowQueue workflowQueue = null;
if (!queueSvcs.Exists(queueId))
{
WorkflowActivityTrace.Activity.TraceEvent(TraceEventType.Information, 0, "CorrelationTokenInvalidatedHandler: creating q {0} ", queueId.GetHashCode());
workflowQueue = queueSvcs.CreateWorkflowQueue(queueId, true);
queueCreator = true;
}
else
{
workflowQueue = queueSvcs.GetWorkflowQueue(queueId);
}
if (this.eventHandler != null)
{
workflowQueue.RegisterForQueueItemAvailable(this.eventHandler);
}
WorkflowSubscriptionService subscriptionService = (WorkflowSubscriptionService)context.GetService(typeof(WorkflowSubscriptionService));
MessageEventSubscription subscription = new MessageEventSubscription(queueId, instanceId);
this.queueName = queueId;
this.subscriptionId = subscription.SubscriptionId;
subscription.InterfaceType = this.interfaceType;
subscription.MethodName = this.followerOperation;
this.interfaceType = null;
this.followerOperation = null;
if (correlationValues != null)
{
foreach (CorrelationProperty property in correlationValues)
{
subscription.CorrelationProperties.Add(property);
}
}
if (this.eventHandler != null)
return;
if (subscriptionService == null)
return;
subscriptionService.CreateSubscription(subscription);
}
private void DeleteSubscription(ActivityExecutionContext context)
{
if (this.queueName == null)
return;
WorkflowQueuingService queueSvcs = context.GetService<WorkflowQueuingService>();
if (queueCreator)
queueSvcs.DeleteWorkflowQueue(this.queueName);
if (this.eventHandler != null)
return;
WorkflowSubscriptionService subscriptionService = context.GetService<WorkflowSubscriptionService>();
if (subscriptionService != null)
subscriptionService.DeleteSubscription(this.subscriptionId);
WorkflowActivityTrace.Activity.TraceEvent(TraceEventType.Information, 0, "CorrelationTokenInvalidatedHandler subscription deleted SubId {0} QueueId {1}", this.subscriptionId, this.queueName);
}
}
}

View File

@@ -0,0 +1,160 @@
using System;
using System.Xml;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.ComponentModel.Design.Serialization;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Runtime.Serialization;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.Runtime;
using System.Globalization;
namespace System.Workflow.Activities
{
internal sealed class CorrelationTokenTypeConverter : ExpandableObjectConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return (sourceType == typeof(string));
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return (destinationType == typeof(string));
}
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
object convertedValue = null;
string correlatorName = value as String;
if (!String.IsNullOrEmpty(correlatorName))
{
foreach (object obj in GetStandardValues(context))
{
CorrelationToken correlator = obj as CorrelationToken;
if (correlator != null && correlator.Name == correlatorName)
{
convertedValue = correlator;
break;
}
}
if (convertedValue == null)
convertedValue = new CorrelationToken(correlatorName);
}
return convertedValue;
}
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
{
object convertedValue = null;
CorrelationToken correlator = value as CorrelationToken;
if (destinationType == typeof(string) && correlator != null)
convertedValue = correlator.Name;
return convertedValue;
}
public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
{
ArrayList values = new ArrayList();
Activity activity = context.Instance as Activity;
if (activity != null)
{
foreach (Activity preceedingActivity in GetPreceedingActivities(activity))
{
PropertyDescriptor correlatorProperty = TypeDescriptor.GetProperties(preceedingActivity)["CorrelationToken"] as PropertyDescriptor;
if (correlatorProperty != null)
{
CorrelationToken correlator = correlatorProperty.GetValue(preceedingActivity) as CorrelationToken;
if (correlator != null && !values.Contains(correlator))
values.Add(correlator);
}
}
}
return new StandardValuesCollection(values);
}
public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
{
return true;
}
public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
{
return false;
}
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
{
PropertyDescriptorCollection properties = base.GetProperties(context, value, attributes);
ArrayList props = new ArrayList(properties);
return new PropertyDescriptorCollection((PropertyDescriptor[])props.ToArray(typeof(PropertyDescriptor)));
}
//
private IEnumerable GetPreceedingActivities(Activity startActivity)
{
Activity currentActivity = null;
Stack<Activity> activityStack = new Stack<Activity>();
activityStack.Push(startActivity);
while ((currentActivity = activityStack.Pop()) != null)
{
if (currentActivity.Parent != null)
{
foreach (Activity siblingActivity in currentActivity.Parent.Activities)
{
if (siblingActivity == currentActivity)
break;
if (siblingActivity.Enabled)
{
if (siblingActivity is CompositeActivity)
{
foreach (Activity containedActivity in GetContainedActivities((CompositeActivity)siblingActivity))
yield return containedActivity;
}
else
{
yield return siblingActivity;
}
}
}
}
activityStack.Push(currentActivity.Parent);
}
yield break;
}
private IEnumerable GetContainedActivities(CompositeActivity activity)
{
if (!activity.Enabled)
yield break;
foreach (Activity containedActivity in activity.Activities)
{
if (containedActivity is CompositeActivity)
{
foreach (Activity nestedActivity in GetContainedActivities((CompositeActivity)containedActivity))
{
if (nestedActivity.Enabled)
yield return nestedActivity;
}
}
else
{
if (containedActivity.Enabled)
yield return containedActivity;
}
}
yield break;
}
}
}

View File

@@ -0,0 +1,117 @@

using System;
using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Proxies;
using System.Workflow.ComponentModel;
using System.Workflow.Runtime;
using System.Workflow.Runtime.Hosting;
using System.Security.Permissions;
using System.Globalization;
namespace System.Workflow.Activities
{
internal sealed class ExternalDataExchangeBinder : Binder
{
Binder defltBinder;
internal ExternalDataExchangeBinder()
{
defltBinder = Type.DefaultBinder;
}
public override MethodBase BindToMethod(BindingFlags bindingAttr,
MethodBase[] match,
ref object[] args,
ParameterModifier[] modifiers,
System.Globalization.CultureInfo culture,
string[] names,
out object state)
{
Object[] argsCopy = new Object[args.Length];
args.CopyTo(argsCopy, 0);
state = null;
try
{
return defltBinder.BindToMethod(bindingAttr, match, ref args, modifiers, culture, names, out state);
}
catch (MissingMethodException) //5% case where when passed null for params.
{
if (match != null && match.Length != 0)
{
for (int i = 0; i < match.Length; ++i)
{
ParameterInfo[] methodParams = match[i].GetParameters();
if (methodParams.Length == argsCopy.Length)
{
for (int j = 0; j < methodParams.Length; ++j)
{
if (!methodParams[j].ParameterType.IsInstanceOfType(argsCopy[j]))
{
if (!(methodParams[j].ParameterType.IsArray && argsCopy[j] == null))
break;
}
if (j + 1 == methodParams.Length)
return match[i];
}
}
}
}
}
return null;
}
public override FieldInfo BindToField(BindingFlags bindingAttr,
FieldInfo[] match,
object value,
CultureInfo culture)
{
return defltBinder.BindToField(bindingAttr, match, value, culture);
}
public override MethodBase SelectMethod(BindingFlags bindingAttr,
MethodBase[] match,
Type[] types,
ParameterModifier[] modifiers)
{
return defltBinder.SelectMethod(bindingAttr, match, types, modifiers);
}
public override PropertyInfo SelectProperty(BindingFlags bindingAttr,
PropertyInfo[] match,
Type returnType,
Type[] indexes,
ParameterModifier[] modifiers
)
{
return defltBinder.SelectProperty(bindingAttr, match, returnType, indexes, modifiers);
}
public override object ChangeType(object value,
Type type,
CultureInfo culture
)
{
return defltBinder.ChangeType(value, type, culture);
}
public override void ReorderArgumentArray(ref object[] args,
object state
)
{
defltBinder.ReorderArgumentArray(ref args, state);
}
}
}

View File

@@ -0,0 +1,381 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
using System;
using System.Diagnostics;
using System.Collections;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Reflection;
using System.Workflow.ComponentModel;
using System.Workflow.Runtime;
using System.Workflow.Runtime.Configuration;
using System.Workflow.Runtime.Hosting;
using System.Runtime.Serialization;
using System.Globalization;
using System.Threading;
using System.Runtime.Serialization.Formatters.Binary;
using System.Configuration;
namespace System.Workflow.Activities
{
internal interface IDeliverMessage
{
object[] PrepareEventArgsArray(object sender, ExternalDataEventArgs eventArgs, out object workItem, out IPendingWork workHandler);
void DeliverMessage(ExternalDataEventArgs eventArgs, IComparable queueName, object message, object workItem, IPendingWork workHandler);
}
[Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")]
public class ExternalDataExchangeServiceSection : ConfigurationSection
{
private const string _services = "Services";
/// <summary> The providers to be instantiated by the service container. </summary>
[ConfigurationProperty(_services, DefaultValue = null)]
public WorkflowRuntimeServiceElementCollection Services
{
get
{
return (WorkflowRuntimeServiceElementCollection)base[_services];
}
}
}
[Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")]
public class ExternalDataExchangeService : WorkflowRuntimeService
{
Dictionary<int, WorkflowMessageEventHandler> eventHandlers = null;
object handlersLock = new object();
private const string configurationSectionAttributeName = "ConfigurationSection";
ExternalDataExchangeServiceSection settings = null;
IDeliverMessage enqueueMessageWrapper = null;
List<object> services;
object servicesLock = new object();
public ExternalDataExchangeService()
{
this.eventHandlers = new Dictionary<int, WorkflowMessageEventHandler>();
this.services = new List<object>();
this.enqueueMessageWrapper = new EnqueueMessageWrapper(this);
}
public ExternalDataExchangeService(string configSectionName)
: this()
{
if (configSectionName == null)
throw new ArgumentNullException("configSectionName");
settings = ConfigurationManager.GetSection(configSectionName) as ExternalDataExchangeServiceSection;
if (settings == null)
throw new ArgumentException(String.Format(CultureInfo.CurrentCulture,
SR.GetString(SR.Error_ConfigurationSectionNotFound), configSectionName));
}
public ExternalDataExchangeService(NameValueCollection parameters)
: this()
{
if (parameters == null)
throw new ArgumentNullException("parameters");
string configurationSectionName = null;
foreach (string key in parameters.Keys)
{
if (key.Equals(configurationSectionAttributeName, StringComparison.OrdinalIgnoreCase))
{
configurationSectionName = parameters[key];
}
else
{
throw new ArgumentException(
String.Format(Thread.CurrentThread.CurrentCulture, SR.GetString(SR.Error_UnknownConfigurationParameter), key), "parameters");
}
}
if (configurationSectionName != null)
{
settings = ConfigurationManager.GetSection(configurationSectionName) as ExternalDataExchangeServiceSection;
if (settings == null)
throw new ArgumentException(String.Format(CultureInfo.CurrentCulture,
SR.GetString(SR.Error_ConfigurationSectionNotFound), configurationSectionName));
}
}
public ExternalDataExchangeService(ExternalDataExchangeServiceSection settings)
: this()
{
if (settings == null)
throw new ArgumentNullException("settings");
this.settings = settings;
}
internal ReadOnlyCollection<object> GetAllServices()
{
ReadOnlyCollection<object> collection;
lock (this.servicesLock)
{
collection = this.services.AsReadOnly();
}
return collection;
}
protected override void Start()
{
if (settings != null)
{
foreach (WorkflowRuntimeServiceElement service in settings.Services)
{
AddService(ServiceFromSettings(service));
}
}
if (this.Runtime != null)
{
base.Start();
}
}
internal void SetEnqueueMessageWrapper(IDeliverMessage wrapper)
{
this.enqueueMessageWrapper = wrapper;
foreach (WorkflowMessageEventHandler eventHandler in this.eventHandlers.Values)
{
eventHandler.EnqueueWrapper = wrapper;
}
}
// Todo: This is duplicate of code in WorkflowRuntime
internal object ServiceFromSettings(WorkflowRuntimeServiceElement serviceSettings)
{
object service = null;
Type t = Type.GetType(serviceSettings.Type, true);
ConstructorInfo serviceProviderAndSettingsConstructor = null;
ConstructorInfo serviceProviderConstructor = null;
ConstructorInfo settingsConstructor = null;
foreach (ConstructorInfo ci in t.GetConstructors())
{
ParameterInfo[] pi = ci.GetParameters();
if (pi.Length == 1)
{
if (typeof(IServiceProvider).IsAssignableFrom(pi[0].ParameterType))
{
serviceProviderConstructor = ci;
}
else if (typeof(NameValueCollection).IsAssignableFrom(pi[0].ParameterType))
{
settingsConstructor = ci;
}
}
else if (pi.Length == 2)
{
if (typeof(IServiceProvider).IsAssignableFrom(pi[0].ParameterType)
&& typeof(NameValueCollection).IsAssignableFrom(pi[1].ParameterType))
{
serviceProviderAndSettingsConstructor = ci;
break;
}
}
}
if (serviceProviderAndSettingsConstructor != null)
{
service = serviceProviderAndSettingsConstructor.Invoke(
new object[] { Runtime, serviceSettings.Parameters });
}
else if (serviceProviderConstructor != null)
{
service = serviceProviderConstructor.Invoke(new object[] { Runtime });
}
else if (settingsConstructor != null)
{
service = settingsConstructor.Invoke(new object[] { serviceSettings.Parameters });
}
else
{
service = Activator.CreateInstance(t);
}
return service;
}
public virtual void AddService(object service)
{
if (service == null)
throw new ArgumentNullException("service");
InterceptService(service, true);
if (this.Runtime != null)
{
this.Runtime.AddService(service);
}
else
{
lock (this.servicesLock)
{
this.services.Add(service);
}
}
}
public virtual void RemoveService(object service)
{
if (service == null)
throw new ArgumentNullException("service");
InterceptService(service, false);
if (this.Runtime != null)
{
this.Runtime.RemoveService(service);
}
else
{
lock (this.servicesLock)
{
this.services.Remove(service);
}
}
}
public virtual object GetService(Type serviceType)
{
if (serviceType == null)
throw new ArgumentNullException("serviceType");
if (this.Runtime != null)
{
return this.Runtime.GetService(serviceType);
}
else
{
lock (this.servicesLock)
{
foreach (object service in this.services)
{
if (serviceType.IsAssignableFrom(service.GetType()))
{
return service;
}
}
return null;
}
}
}
internal void InterceptService(object service, bool add)
{
bool isDataExchangeService = false;
Type[] interfaceTypes = service.GetType().GetInterfaces();
foreach (Type type in interfaceTypes)
{
object[] attributes = type.GetCustomAttributes(typeof(ExternalDataExchangeAttribute), false);
if (attributes.Length == 0)
continue;
if (this.Runtime != null && this.Runtime.GetService(type) != null && add)
throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, SR.GetString(SR.Error_ExternalDataExchangeServiceExists), type));
isDataExchangeService = true;
EventInfo[] events = type.GetEvents();
if (events == null)
continue;
foreach (EventInfo e in events)
{
WorkflowMessageEventHandler handler = null;
int hash = type.GetHashCode() ^ e.Name.GetHashCode();
lock (handlersLock)
{
if (!this.eventHandlers.ContainsKey(hash))
{
handler = new WorkflowMessageEventHandler(type, e, this.enqueueMessageWrapper);
this.eventHandlers.Add(hash, handler);
}
else
{
handler = this.eventHandlers[hash];
}
}
AddRemove(service, handler.Delegate, add, e.Name);
}
}
if (!isDataExchangeService)
throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, SR.GetString(SR.Error_ServiceMissingExternalDataExchangeInterface)));
}
private void AddRemove(object addedservice, Delegate delg, bool add, string eventName)
{
try
{
string eventAction;
if (add)
eventAction = "add_" + eventName;
else
eventAction = "remove_" + eventName;
Type serviceType = addedservice.GetType();
if (delg != null)
{
// add or remove interception handler
object[] del = { delg };
serviceType.InvokeMember(eventAction, BindingFlags.InvokeMethod, null, addedservice, del, null);
}
}
catch (Exception e)
{
if (IsIrrecoverableException(e))
{
throw;
}
// cannot intercept this event
}
}
internal static bool IsIrrecoverableException(Exception e)
{
return ((e is OutOfMemoryException) ||
(e is StackOverflowException) ||
(e is ThreadInterruptedException) ||
(e is ThreadAbortException));
}
class EnqueueMessageWrapper : IDeliverMessage
{
ExternalDataExchangeService eds;
public EnqueueMessageWrapper(ExternalDataExchangeService eds)
{
this.eds = eds;
}
public object[] PrepareEventArgsArray(object sender, ExternalDataEventArgs eventArgs, out object workItem, out IPendingWork workHandler)
{
// remove the batch items from the event args, only the runtime needs this data
// and it is not necessarily serializable.
workItem = eventArgs.WorkItem;
eventArgs.WorkItem = null;
workHandler = eventArgs.WorkHandler;
eventArgs.WorkHandler = null;
return new object[] { sender, eventArgs };
}
public void DeliverMessage(ExternalDataEventArgs eventArgs, IComparable queueName, object message, object workItem, IPendingWork workHandler)
{
WorkflowInstance workflowInstance = this.eds.Runtime.GetWorkflow(eventArgs.InstanceId);
if (eventArgs.WaitForIdle)
{
workflowInstance.EnqueueItemOnIdle(queueName, message, workHandler, workItem);
}
else
{
workflowInstance.EnqueueItem(queueName, message, workHandler, workItem);
}
}
}
}
}

View File

@@ -0,0 +1,70 @@
#region Using directives
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Collections;
using System.Reflection;
using System.Runtime.Serialization;
using System.Workflow.ComponentModel;
using System.Workflow.Runtime;
using System.Workflow.Runtime.Hosting;
using System.Runtime.Remoting.Messaging;
#endregion
namespace System.Workflow.Activities
{
[Serializable]
internal sealed class FollowerQueueCreator : IActivityEventListener<QueueEventArgs>
{
string followerOperation;
object sync = new object();
internal FollowerQueueCreator(string operation)
{
this.followerOperation = operation;
}
public override bool Equals(object obj)
{
if (obj == null)
return false;
FollowerQueueCreator equalsObject = obj as FollowerQueueCreator;
if (this.followerOperation == equalsObject.followerOperation)
return true;
return false;
}
public override int GetHashCode()
{
return this.followerOperation.GetHashCode();
}
#region IActivityEventListener<QueueEventArgs> Members
void IActivityEventListener<QueueEventArgs>.OnEvent(object sender, QueueEventArgs args)
{
lock (sync)
{
WorkflowQueue queue = (WorkflowQueue)sender;
// create the queue after extracting the correlation values from the message
EventQueueName staticId = (EventQueueName)queue.QueueName;
WorkflowActivityTrace.Activity.TraceEvent(TraceEventType.Information, 0, "FollowerQueueCreator: initialized on operation {0} for follower {1}", staticId.InterfaceType.Name + staticId.MethodName, this.followerOperation);
IMethodMessage message = queue.Peek() as IMethodMessage;
ICollection<CorrelationProperty> corrValues = CorrelationResolver.ResolveCorrelationValues(staticId.InterfaceType, staticId.MethodName, message.Args, false);
EventQueueName queueName = new EventQueueName(staticId.InterfaceType, this.followerOperation, corrValues);
if (!queue.QueuingService.Exists(queueName))
{
WorkflowActivityTrace.Activity.TraceEvent(TraceEventType.Information, 0, "FollowerQueueCreator::CreateQueue creating q {0}", queueName.GetHashCode());
queue.QueuingService.CreateWorkflowQueue(queueName, true);
}
}
}
#endregion
}
}

View File

@@ -0,0 +1,70 @@
#region Using directives
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Collections;
using System.Reflection;
using System.Runtime.Serialization;
using System.Workflow.ComponentModel;
using System.Workflow.Runtime;
using System.Workflow.Runtime.Hosting;
using System.Runtime.Remoting.Messaging;
#endregion
namespace System.Workflow.Activities
{
[Serializable]
internal sealed class FollowerQueueCreator : IActivityEventListener<QueueEventArgs>
{
string followerOperation;
object [....] = new object();
internal FollowerQueueCreator(string operation)
{
this.followerOperation = operation;
}
public override bool Equals(object obj)
{
if (obj == null)
return false;
FollowerQueueCreator equalsObject = obj as FollowerQueueCreator;
if (this.followerOperation == equalsObject.followerOperation)
return true;
return false;
}
public override int GetHashCode()
{
return this.followerOperation.GetHashCode();
}
#region IActivityEventListener<QueueEventArgs> Members
void IActivityEventListener<QueueEventArgs>.OnEvent(object sender, QueueEventArgs args)
{
lock ([....])
{
WorkflowQueue queue = (WorkflowQueue)sender;
// create the queue after extracting the correlation values from the message
EventQueueName staticId = (EventQueueName)queue.QueueName;
WorkflowActivityTrace.Activity.TraceEvent(TraceEventType.Information, 0, "FollowerQueueCreator: initialized on operation {0} for follower {1}", staticId.InterfaceType.Name + staticId.MethodName, this.followerOperation);
IMethodMessage message = queue.Peek() as IMethodMessage;
ICollection<CorrelationProperty> corrValues = CorrelationResolver.ResolveCorrelationValues(staticId.InterfaceType, staticId.MethodName, message.Args, false);
EventQueueName queueName = new EventQueueName(staticId.InterfaceType, this.followerOperation, corrValues);
if (!queue.QueuingService.Exists(queueName))
{
WorkflowActivityTrace.Activity.TraceEvent(TraceEventType.Information, 0, "FollowerQueueCreator::CreateQueue creating q {0}", queueName.GetHashCode());
queue.QueuingService.CreateWorkflowQueue(queueName, true);
}
}
}
#endregion
}
}

View File

@@ -0,0 +1,54 @@
#region Using directives
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Serialization;
using System.Security;
using System.Security.Permissions;
using System.Security.Principal;
#endregion
namespace System.Workflow.Activities
{
[Serializable]
internal sealed class IdentityContextData : ILogicalThreadAffinative, ISerializable
{
internal const string IdentityContext = "__identitycontext__";
String identity;
internal IdentityContextData(String identity)
{
this.identity = identity;
}
private IdentityContextData(SerializationInfo info, StreamingContext context)
{
SerializationInfoEnumerator enumerator = info.GetEnumerator();
while (enumerator.MoveNext())
{
if (enumerator.Name.Equals("identity"))
{
this.identity = (String)enumerator.Value;
}
}
}
[SecurityPermission( SecurityAction.Demand, SerializationFormatter = true)]
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
if (this.identity != null)
info.AddValue("identity", identity.ToString());
}
internal String Identity
{
get
{
return identity;
}
}
}
}

View File

@@ -0,0 +1,129 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Text;
using System.Workflow.ComponentModel;
using System.Workflow.Runtime;
using System.Workflow.Runtime.Hosting;
namespace System.Workflow.Activities
{
[Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")]
public abstract class WorkflowSubscriptionService
{
public abstract void CreateSubscription(MessageEventSubscription subscription);
public abstract void DeleteSubscription(Guid subscriptionId);
}
[Serializable]
[Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")]
public class MessageEventSubscription
{
Type interfaceType;
String operation;
List<CorrelationProperty> predicates;
Guid subscriptionId;
Guid workflowInstanceId;
IComparable queueName;
protected MessageEventSubscription()
{
}
public MessageEventSubscription(IComparable queueName, Guid instanceId)
: this(queueName, instanceId, Guid.NewGuid())
{
}
public MessageEventSubscription(IComparable queueName, Guid instanceId, Guid subscriptionId)
: this(queueName, instanceId, null, null, subscriptionId)
{
}
public MessageEventSubscription(IComparable queueName, Guid subscriptionId, Type interfaceType, String operation)
: this(queueName, Guid.Empty, interfaceType, operation, subscriptionId)
{
}
public MessageEventSubscription(IComparable queueName, Guid instanceId, Type interfaceType, String operation, Guid subscriptionId)
{
this.queueName = queueName;
this.workflowInstanceId = instanceId;
this.subscriptionId = subscriptionId;
this.interfaceType = interfaceType;
this.operation = operation;
this.predicates = new List<CorrelationProperty>();
}
public virtual Type InterfaceType
{
get
{
return this.interfaceType;
}
set
{
this.interfaceType = value;
}
}
public virtual String MethodName
{
get
{
return this.operation;
}
set
{
this.operation = value;
}
}
public virtual ICollection<CorrelationProperty> CorrelationProperties
{
get
{
return this.predicates;
}
}
//A Unique id for this subscription. It is needed because
//QueueName is not always guaranteed to be Unique.
//Needed in case of Multiple Subscription on Same Queue
public virtual Guid SubscriptionId
{
get
{
return this.subscriptionId;
}
}
public virtual IComparable QueueName
{
get
{
return this.queueName;
}
protected set
{
this.queueName = value;
}
}
public virtual Guid WorkflowInstanceId
{
get
{
return this.workflowInstanceId;
}
}
}
}

View File

@@ -0,0 +1,278 @@
#pragma warning disable 1634, 1691
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
using System;
using System.Text;
using System.Workflow.ComponentModel;
using System.Collections;
using System.Collections.Generic;
using System.Workflow.Runtime;
namespace System.Workflow.Activities
{
[Serializable]
[Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")]
public sealed class EventQueueName : IComparable
{
Type interfaceType;
string operation;
CorrelationProperty[] correlationValues;
string activityId;
[NonSerialized]
string assemblyQualifiedName;
[NonSerialized]
String stringifiedKey;
private string AssemblyQualifiedName
{
get
{
if (assemblyQualifiedName == null)
{
assemblyQualifiedName = this.interfaceType.AssemblyQualifiedName;
}
return assemblyQualifiedName;
}
}
public EventQueueName(Type interfaceType, string operation)
{
if (interfaceType == null)
throw new ArgumentNullException("interfaceType");
if (operation == null)
throw new ArgumentNullException("operation");
this.interfaceType = interfaceType;
this.operation = operation;
}
public EventQueueName(Type interfaceType, string operation, ICollection<CorrelationProperty> propertyValues)
: this(interfaceType, operation)
{
if (propertyValues != null)
{
this.correlationValues = new CorrelationProperty[propertyValues.Count];
propertyValues.CopyTo(this.correlationValues, 0);
}
}
internal EventQueueName(Type interfaceType, string operation, string activityId)
: this(interfaceType, operation)
{
this.activityId = activityId;
}
// properties
public Type InterfaceType
{
get
{
return this.interfaceType;
}
}
public string MethodName
{
get
{
return this.operation;
}
}
public CorrelationProperty[] GetCorrelationValues()
{
return this.correlationValues;
}
public int CompareTo(Object toCompare)
{
if (toCompare is EventQueueName)
return this.CompareTo(toCompare as EventQueueName);
else
return -1;
}
// IComparable implementation
public int CompareTo(EventQueueName eventQueueName)
{
if (eventQueueName == null)
return -1;
// compare operation
int compared = StringComparer.Ordinal.Compare(this.MethodName, eventQueueName.MethodName);
if (compared == 0)
{
// compare type names
#pragma warning disable 56506
compared = StringComparer.Ordinal.Compare(AssemblyQualifiedName, eventQueueName.AssemblyQualifiedName);
#pragma warning restore 56506
if (compared == 0)
{
if (this.correlationValues != null)
{
compared = (eventQueueName.correlationValues != null) ? (this.correlationValues.Length - eventQueueName.correlationValues.Length) : -1;
if (compared == 0)
{
// compare correlation values
for (int i = 0; i < this.correlationValues.Length; i++)
{
if (this.correlationValues[i] == null || eventQueueName.correlationValues[i] == null)
{
compared = -1;
break; // match failed
}
object leftValue = this.correlationValues[i].Value;
object rightValue = FindCorrelationValue(this.correlationValues[i].Name, eventQueueName.correlationValues);
#pragma warning suppress 56506
if (leftValue == null && rightValue == null)
{
continue;
}
// do the explicit equals check
if (leftValue != null)
{
IComparable comparable = leftValue as IComparable;
if (comparable != null)
{
compared = comparable.CompareTo(rightValue);
if (compared != 0)
{
break; // match failed
}
}
else if ((!leftValue.Equals(rightValue)))
{
compared = -1;
break; // match failed
}
}
else
{
compared = -1;
break; // match failed
}
}
}
}
}
}
return compared;
}
public override bool Equals(object obj)
{
EventQueueName k = obj as EventQueueName;
//Without the cast we end up in op_Equality below
if ((object)k == null)
return false;
return 0 == CompareTo(k);
}
public static bool operator ==(EventQueueName queueKey1, EventQueueName queueKey2)
{
bool equality = false;
if ((object)queueKey1 != null)
{
if ((object)queueKey2 != null)
{
equality = (0 == queueKey1.CompareTo(queueKey2));
}
}
else if ((object)queueKey2 == null)
{
equality = true;
}
return equality;
}
public static bool operator !=(EventQueueName queueKey1, EventQueueName queueKey2)
{
return !(queueKey1 == queueKey2);
}
public static bool operator <(EventQueueName queueKey1, EventQueueName queueKey2)
{
if (queueKey1 == null)
throw new ArgumentNullException("queueKey1");
if (queueKey2 == null)
throw new ArgumentNullException("queueKey2");
return (queueKey1.CompareTo(queueKey2) < 0);
}
public static bool operator >(EventQueueName queueKey1, EventQueueName queueKey2)
{
if (queueKey1 == null)
throw new ArgumentNullException("queueKey1");
if (queueKey2 == null)
throw new ArgumentNullException("queueKey2");
return (queueKey1.CompareTo(queueKey2) > 0);
}
public override int GetHashCode()
{
if (String.IsNullOrEmpty(this.activityId))
return (AssemblyQualifiedName.GetHashCode() ^ this.operation.GetHashCode());
return (AssemblyQualifiedName.GetHashCode() ^ this.operation.GetHashCode() ^ this.activityId.GetHashCode());
}
public override string ToString()
{
if (stringifiedKey == null)
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.AppendLine("Message Properties");
stringBuilder.AppendLine("Interface Type:" + this.interfaceType.ToString());
stringBuilder.AppendLine("Method Name:" + this.operation.ToString());
stringBuilder.AppendLine("CorrelationValues:");
if (correlationValues != null)
{
foreach (CorrelationProperty pred in correlationValues)
{
if (pred != null && pred.Value != null)
stringBuilder.AppendLine(pred.Value.ToString());
}
}
stringifiedKey = stringBuilder.ToString();
}
return stringifiedKey;
}
object FindCorrelationValue(string name, CorrelationProperty[] correlationValues)
{
object value = null;
foreach (CorrelationProperty property in correlationValues)
{
if (property != null && property.Name == name)
{
value = property.Value;
break;
}
}
return value;
}
}
}

View File

@@ -0,0 +1,342 @@
#pragma warning disable 1634, 1691
using System;
using System.Diagnostics;
using System.Collections;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.Remoting.Messaging;
using System.Workflow.Runtime;
using System.Security.Principal;
using System.Threading;
using System.Globalization;
namespace System.Workflow.Activities
{
internal interface IMethodResponseMessage
{
void SendResponse(ICollection outArgs);
void SendException(Exception exception);
Exception Exception { get; }
ICollection OutArgs { get; }
}
[Serializable]
internal sealed class MethodMessage : IMethodMessage, IMethodResponseMessage
{
[NonSerialized]
Type interfaceType;
[NonSerialized]
string methodName;
[NonSerialized]
object[] args;
[NonSerialized]
ManualResetEvent returnValueSignalEvent;
object[] clonedArgs;
LogicalCallContext callContext;
ICollection outArgs;
Exception exception;
[NonSerialized]
bool responseSet = false;
Guid callbackCookie;
[NonSerialized]
MethodMessage previousMessage = null;
static Dictionary<Guid, MethodMessage> staticMethodMessageMap = new Dictionary<Guid, MethodMessage>();
static Object syncRoot = new Object();
internal MethodMessage(Type interfaceType, string methodName,
object[] args, String identity) :
this(interfaceType, methodName, args, identity, false)
{
}
internal MethodMessage(Type interfaceType, string methodName,
object[] args, String identity, bool responseRequired)
{
this.interfaceType = interfaceType;
this.methodName = methodName;
this.args = args;
callContext = GetLogicalCallContext();
if (responseRequired)
returnValueSignalEvent = new ManualResetEvent(false);
PopulateIdentity(callContext, identity);
Clone();
}
[OnSerializing]
void OnSerializing(StreamingContext context)
{
if (returnValueSignalEvent != null && !responseSet)
{
callbackCookie = Guid.NewGuid();
lock (syncRoot)
{
staticMethodMessageMap.Add(callbackCookie, previousMessage ?? this);
}
}
}
[OnDeserialized]
void OnDeserialized(StreamingContext context)
{
if (callbackCookie != Guid.Empty)
{
lock (syncRoot)
{
if (staticMethodMessageMap.TryGetValue(callbackCookie, out previousMessage))
staticMethodMessageMap.Remove(callbackCookie);
}
if (previousMessage != null)
{
this.responseSet = previousMessage.responseSet;
this.returnValueSignalEvent = previousMessage.returnValueSignalEvent;
}
}
callbackCookie = Guid.Empty;
}
string IMethodMessage.GetArgName(int index)
{
throw new NotImplementedException();
}
object IMethodMessage.GetArg(int argNum)
{
return this.clonedArgs[argNum];
}
string IMethodMessage.Uri
{
#pragma warning disable 56503
// not implemented
get { throw new NotImplementedException(); }
#pragma warning restore 56503
}
string IMethodMessage.MethodName
{
get { return this.methodName; }
}
string IMethodMessage.TypeName
{
get
{
return (this.interfaceType.ToString());
}
}
object IMethodMessage.MethodSignature
{
#pragma warning disable 56503
get { throw new NotImplementedException(); }
#pragma warning restore 56503
}
object[] IMethodMessage.Args
{
get
{
return this.clonedArgs;
}
}
object Clone()
{
object[] clones = new object[this.args.Length];
for (int i = 0; i < this.args.Length; i++)
{
clones[i] = Clone(this.args[i]);
}
this.clonedArgs = clones;
return clones;
}
object Clone(object source)
{
if (source == null || source.GetType().IsValueType)
return source;
ICloneable clone = source as ICloneable;
if (clone != null)
return clone.Clone();
BinaryFormatter formatter = new BinaryFormatter();
System.IO.MemoryStream stream = new System.IO.MemoryStream(1024);
try
{
formatter.Serialize(stream, source);
}
catch (SerializationException e)
{
throw new InvalidOperationException(SR.GetString(SR.Error_EventArgumentSerializationException), e);
}
stream.Position = 0;
object cloned = formatter.Deserialize(stream);
return cloned;
}
int IMethodMessage.ArgCount
{
get { return this.clonedArgs.Length; }
}
bool IMethodMessage.HasVarArgs
{
#pragma warning disable 56503
get { throw new NotImplementedException(); }
#pragma warning restore 56503
}
LogicalCallContext IMethodMessage.LogicalCallContext
{
get { return callContext; }
}
MethodBase IMethodMessage.MethodBase
{
#pragma warning disable 56503
get { throw new NotImplementedException(); }
#pragma warning restore 56503
}
IDictionary System.Runtime.Remoting.Messaging.IMessage.Properties
{
#pragma warning disable 56503
get { throw new NotImplementedException(); }
#pragma warning restore 56503
}
void PopulateIdentity(LogicalCallContext callContext, String identity)
{
callContext.SetData(IdentityContextData.IdentityContext, new IdentityContextData(identity));
}
static LogicalCallContext singletonCallContext;
static Object syncObject = new Object();
static LogicalCallContext GetLogicalCallContext()
{
lock (syncObject)
{
if (singletonCallContext == null)
{
CallContextProxy contextProxy = new CallContextProxy(typeof(IDisposable));
IDisposable disposable = (IDisposable)contextProxy.GetTransparentProxy();
disposable.Dispose();
singletonCallContext = contextProxy.CallContext;
}
return singletonCallContext.Clone() as LogicalCallContext;
}
}
#region IMethodResponseMessage implementation
internal IMethodResponseMessage WaitForResponseMessage()
{
// todo wait for certain timeout
this.returnValueSignalEvent.WaitOne();
this.returnValueSignalEvent = null;
return this;
}
public void SendResponse(ICollection outArgs)
{
if (this.returnValueSignalEvent == null)
throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, SR.GetString(SR.Error_WorkflowInstanceDehydratedBeforeSendingResponse)));
if (!this.responseSet)
{
this.OutArgs = outArgs;
this.returnValueSignalEvent.Set();
this.responseSet = true;
}
}
public void SendException(Exception exception)
{
if (this.returnValueSignalEvent == null)
throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, SR.GetString(SR.Error_WorkflowInstanceDehydratedBeforeSendingResponse)));
if (!this.responseSet)
{
this.Exception = exception;
this.returnValueSignalEvent.Set();
this.responseSet = true;
}
}
public Exception Exception
{
get
{
return this.exception;
}
private set
{
if (previousMessage != null)
previousMessage.Exception = value;
this.exception = value;
}
}
public ICollection OutArgs
{
get
{
return this.outArgs;
}
private set
{
if (previousMessage != null)
previousMessage.OutArgs = value;
this.outArgs = value;
}
}
#endregion
private sealed class CallContextProxy : System.Runtime.Remoting.Proxies.RealProxy
{
LogicalCallContext callContext;
internal LogicalCallContext CallContext
{
get
{
return callContext;
}
}
internal CallContextProxy(Type proxiedType)
: base(proxiedType)
{
}
public override System.Runtime.Remoting.Messaging.IMessage Invoke(System.Runtime.Remoting.Messaging.IMessage msg)
{
IMethodCallMessage methodCallMessage = msg as IMethodCallMessage;
this.callContext = methodCallMessage.LogicalCallContext.Clone() as LogicalCallContext;
return new ReturnMessage(null, null, 0, methodCallMessage.LogicalCallContext, methodCallMessage);
}
}
}
}

View File

@@ -0,0 +1,176 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
#region Using directives
using System;
using System.Diagnostics;
using System.Collections;
using System.Reflection;
using System.Runtime.Serialization;
using System.Workflow.ComponentModel;
using System.Workflow.Runtime;
using System.Workflow.Runtime.Hosting;
using System.Security.Principal;
#endregion
namespace System.Workflow.Activities
{
[AttributeUsageAttribute(AttributeTargets.Interface, AllowMultiple = false, Inherited = false)]
[Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")]
public sealed class ExternalDataExchangeAttribute : Attribute
{
}
[AttributeUsageAttribute(AttributeTargets.Event | AttributeTargets.Method, AllowMultiple = false)]
[Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")]
public sealed class CorrelationInitializerAttribute : Attribute
{
}
[AttributeUsageAttribute(AttributeTargets.Interface, AllowMultiple = true)]
[Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")]
public sealed class CorrelationParameterAttribute : Attribute
{
private string name = string.Empty;
public CorrelationParameterAttribute(string name)
{
this.name = name;
}
public string Name
{
get
{
return this.name;
}
}
}
[AttributeUsageAttribute(AttributeTargets.Delegate | AttributeTargets.Event | AttributeTargets.Method, AllowMultiple = true)]
[Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")]
public sealed class CorrelationAliasAttribute : Attribute
{
private string path;
private string name;
public CorrelationAliasAttribute(String name, String path)
{
this.path = path;
this.name = name;
}
public String Name
{
get
{
return this.name;
}
}
public String Path
{
get
{
return path;
}
}
}
[Serializable]
[Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")]
public class ExternalDataEventArgs : EventArgs
{
Guid instanceId;
object batchworkItem;
IPendingWork batchworkHandler;
String identity;
bool waitForIdle;
public ExternalDataEventArgs()
: this(Guid.Empty, null, null, false)
{
}
public ExternalDataEventArgs(Guid instanceId)
: this(instanceId, null, null, false)
{
}
public ExternalDataEventArgs(Guid instanceId, IPendingWork workHandler, object workItem, bool waitForIdle)
{
this.instanceId = instanceId;
this.batchworkHandler = workHandler;
this.batchworkItem = workItem;
this.waitForIdle = waitForIdle;
}
public ExternalDataEventArgs(Guid instanceId, IPendingWork workHandler, object workItem)
: this(instanceId, workHandler, workItem, false)
{
}
public Guid InstanceId
{
get
{
return this.instanceId;
}
set
{
this.instanceId = value;
}
}
public object WorkItem
{
get
{
return this.batchworkItem;
}
set
{
this.batchworkItem = value;
}
}
public IPendingWork WorkHandler
{
get
{
return this.batchworkHandler;
}
set
{
this.batchworkHandler = value;
}
}
public String Identity
{
get
{
return this.identity;
}
set
{
this.identity = value;
}
}
public bool WaitForIdle
{
get
{
return this.waitForIdle;
}
set
{
this.waitForIdle = value;
}
}
}
}

View File

@@ -0,0 +1,161 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
using System;
using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Workflow.ComponentModel;
using System.Workflow.Runtime;
using System.Workflow.Runtime.Hosting;
using System.Security.Principal;
using System.Runtime.Serialization;
namespace System.Workflow.Activities
{
[Serializable]
[Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")]
public sealed class EventDeliveryFailedException : SystemException
{
public EventDeliveryFailedException()
{
}
public EventDeliveryFailedException(String message)
: base(message)
{
}
public EventDeliveryFailedException(String message, Exception innerException)
: base(message, innerException)
{
}
private EventDeliveryFailedException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
}
[Serializable]
internal sealed class WorkflowMessageEventHandler
{
Type proxiedType;
string eventName;
[NonSerialized]
Type eventHandlerType;
[NonSerialized]
IDeliverMessage enqueueWrapper;
internal WorkflowMessageEventHandler(Type proxiedType, EventInfo eventInfo, IDeliverMessage enqueueWrapper)
{
this.proxiedType = proxiedType;
this.eventName = eventInfo.Name;
this.eventHandlerType = eventInfo.EventHandlerType;
this.enqueueWrapper = enqueueWrapper;
}
internal IDeliverMessage EnqueueWrapper
{
get
{
return this.enqueueWrapper;
}
set
{
if (value == null)
{
throw new ArgumentNullException("value");
}
this.enqueueWrapper = value;
}
}
internal Delegate Delegate
{
get
{
MethodInfo interceptedHandler = this.eventHandlerType.GetMethod("Invoke");
ParameterInfo[] parameters = interceptedHandler.GetParameters();
bool isValidParameter = false;
if (parameters.Length == 2)
{
if (parameters[1].ParameterType.IsSubclassOf(typeof(ExternalDataEventArgs))
|| parameters[1].ParameterType == (typeof(ExternalDataEventArgs)))
isValidParameter = true;
}
if (isValidParameter)
{
MethodInfo mHandler = typeof(WorkflowMessageEventHandler).GetMethod("EventHandler");
return (Delegate)Activator.CreateInstance(eventHandlerType, new object[] { this, mHandler.MethodHandle.GetFunctionPointer() });
}
return null;
}
}
public void EventHandler(object sender, ExternalDataEventArgs eventArgs)
{
if (eventArgs == null)
{
throw new ArgumentNullException("eventArgs");
}
try
{
object workItem;
IPendingWork workHandler;
object[] args = this.enqueueWrapper.PrepareEventArgsArray(sender, eventArgs, out workItem, out workHandler);
EventQueueName key = GetKey(args);
String securityIdentifier = null;
if (eventArgs.Identity == null)
{
IIdentity identity = System.Threading.Thread.CurrentPrincipal.Identity;
WindowsIdentity windowsIdentity = identity as WindowsIdentity;
if (windowsIdentity != null && windowsIdentity.User != null)
securityIdentifier = windowsIdentity.User.Translate(typeof(NTAccount)).ToString();
else if (identity != null)
securityIdentifier = identity.Name;
eventArgs.Identity = securityIdentifier;
}
else
{
securityIdentifier = eventArgs.Identity;
}
MethodMessage message = new MethodMessage(this.proxiedType, this.eventName, args, securityIdentifier);
WorkflowActivityTrace.Activity.TraceEvent(TraceEventType.Information, 0, "Firing event {0} for instance {1}", this.eventName, eventArgs.InstanceId);
this.enqueueWrapper.DeliverMessage(eventArgs, key, message, workItem, workHandler);
}
catch (Exception e)
{
if (ExternalDataExchangeService.IsIrrecoverableException(e))
{
throw;
}
else
{
throw new EventDeliveryFailedException(SR.GetString(SR.Error_EventDeliveryFailedException, this.proxiedType, this.eventName, eventArgs.InstanceId), e);
}
}
}
private EventQueueName GetKey(object[] eventArgs)
{
bool provideInitializerTokens = CorrelationResolver.IsInitializingMember(this.proxiedType, this.eventName, eventArgs);
ICollection<CorrelationProperty> predicates = CorrelationResolver.ResolveCorrelationValues(this.proxiedType, this.eventName, eventArgs, provideInitializerTokens);
return new EventQueueName(this.proxiedType, this.eventName, predicates);
}
}
}