354 lines
14 KiB
C#
354 lines
14 KiB
C#
//------------------------------------------------------------
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//------------------------------------------------------------
|
|
|
|
namespace System.Workflow.Activities
|
|
{
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Reflection;
|
|
using System.Runtime;
|
|
using System.ServiceModel;
|
|
using System.ServiceModel.Description;
|
|
using System.Workflow.ComponentModel;
|
|
using System.Workflow.ComponentModel.Compiler;
|
|
|
|
internal static class ServiceOperationHelpers
|
|
{
|
|
public static string GetOperationName(IServiceProvider serviceProvider, MethodInfo methodInfo)
|
|
{
|
|
Fx.Assert((methodInfo != null), " MethoInfo cannot be null");
|
|
|
|
string operationName = methodInfo.Name;
|
|
object[] operationContractAttribs = methodInfo.GetCustomAttributes(typeof(OperationContractAttribute), true);
|
|
if (operationContractAttribs != null && operationContractAttribs.Length > 0)
|
|
{
|
|
if (operationContractAttribs[0] is OperationContractAttribute)
|
|
{
|
|
OperationContractAttribute operationContractAttribute = operationContractAttribs[0] as OperationContractAttribute;
|
|
if (!String.IsNullOrEmpty(operationContractAttribute.Name))
|
|
{
|
|
operationName = operationContractAttribute.Name;
|
|
}
|
|
}
|
|
if (operationContractAttribs[0] is AttributeInfoAttribute)
|
|
{
|
|
AttributeInfoAttribute attribInfoAttrib = operationContractAttribs[0] as AttributeInfoAttribute;
|
|
string propertyName = "Name";
|
|
string namePropertyValue;
|
|
if (TryGetArgumentValueAs<string>(serviceProvider, attribInfoAttrib.AttributeInfo, propertyName, out namePropertyValue))
|
|
{
|
|
operationName = namePropertyValue;
|
|
}
|
|
}
|
|
}
|
|
return operationName;
|
|
}
|
|
|
|
public static PropertyDescriptor GetServiceOperationInfoPropertyDescriptor(Activity activity)
|
|
{
|
|
if (activity is ReceiveActivity)
|
|
{
|
|
return TypeDescriptor.GetProperties(activity)[ReceiveActivity.ServiceOperationInfoProperty.Name];
|
|
}
|
|
else
|
|
{
|
|
Fx.Assert(activity is SendActivity, " only Receive and Send activities are valid inputs to this method");
|
|
return TypeDescriptor.GetProperties(activity)[SendActivity.ServiceOperationInfoProperty.Name];
|
|
}
|
|
}
|
|
|
|
public static bool IsAsyncOperation(IServiceProvider serviceProvider, MethodInfo methodInfo)
|
|
{
|
|
if (serviceProvider == null)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("serviceProvider");
|
|
}
|
|
|
|
if (methodInfo == null)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("methodInfo");
|
|
}
|
|
|
|
bool isAsync = false;
|
|
object[] operationContractAttribs = methodInfo.GetCustomAttributes(typeof(OperationContractAttribute), true);
|
|
Fx.Assert(operationContractAttribs != null, "returned attribs list cannot be null");
|
|
Fx.Assert(operationContractAttribs.Length > 0, "operation doesnt seem to be a valid operationcontract");
|
|
|
|
if (operationContractAttribs[0] is OperationContractAttribute)
|
|
{
|
|
OperationContractAttribute operationContractAttribute = operationContractAttribs[0] as OperationContractAttribute;
|
|
isAsync = operationContractAttribute.AsyncPattern;
|
|
}
|
|
if (operationContractAttribs[0] is AttributeInfoAttribute)
|
|
{
|
|
AttributeInfoAttribute attribInfoAttrib = operationContractAttribs[0] as AttributeInfoAttribute;
|
|
isAsync = GetOperationAsyncPattern(serviceProvider, attribInfoAttrib.AttributeInfo);
|
|
}
|
|
|
|
return isAsync;
|
|
}
|
|
|
|
public static bool IsInitiatingOperation(IServiceProvider serviceProvider, MethodInfo methodInfo)
|
|
{
|
|
if (serviceProvider == null)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("serviceProvider");
|
|
}
|
|
|
|
if (methodInfo == null)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("methodInfo");
|
|
}
|
|
|
|
bool isInitiating = true;
|
|
object[] operationContractAttribs = methodInfo.GetCustomAttributes(typeof(OperationContractAttribute), true);
|
|
Fx.Assert(operationContractAttribs != null, "returned attribs list cannot be null");
|
|
Fx.Assert(operationContractAttribs.Length > 0, "operation doesnt seem to be a valid operationcontract");
|
|
|
|
if (operationContractAttribs[0] is OperationContractAttribute)
|
|
{
|
|
OperationContractAttribute operationContractAttribute = operationContractAttribs[0] as OperationContractAttribute;
|
|
isInitiating = operationContractAttribute.IsInitiating;
|
|
}
|
|
if (operationContractAttribs[0] is AttributeInfoAttribute)
|
|
{
|
|
AttributeInfoAttribute attribInfoAttrib = operationContractAttribs[0] as AttributeInfoAttribute;
|
|
isInitiating = IsInitiatingOperationContract(serviceProvider, attribInfoAttrib.AttributeInfo);
|
|
}
|
|
|
|
return isInitiating;
|
|
}
|
|
|
|
public static bool IsNullableType(Type type)
|
|
{
|
|
return (Nullable.GetUnderlyingType(type.IsByRef ? type.GetElementType() : type) != null);
|
|
}
|
|
|
|
public static bool IsValidServiceContract(Type contractType)
|
|
{
|
|
if (contractType == null)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("contractType");
|
|
}
|
|
|
|
object[] contractAttribs = contractType.GetCustomAttributes(typeof(ServiceContractAttribute), false);
|
|
if (contractAttribs != null && contractAttribs.Length > 0)
|
|
{
|
|
if (contractAttribs[0] is ServiceContractAttribute)
|
|
{
|
|
return true;
|
|
}
|
|
if (contractAttribs[0] is AttributeInfoAttribute)
|
|
{
|
|
AttributeInfoAttribute attribInfoAttrib = contractAttribs[0] as AttributeInfoAttribute;
|
|
if (typeof(ServiceContractAttribute).IsAssignableFrom(attribInfoAttrib.AttributeInfo.AttributeType))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public static bool IsValidServiceOperation(MethodInfo methodInfo)
|
|
{
|
|
if (methodInfo == null)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("methodInfo");
|
|
}
|
|
|
|
object[] operationContractAttribs = methodInfo.GetCustomAttributes(typeof(OperationContractAttribute), true);
|
|
if (operationContractAttribs != null && operationContractAttribs.Length > 0)
|
|
{
|
|
if (operationContractAttribs[0] is OperationContractAttribute)
|
|
{
|
|
return true;
|
|
}
|
|
if (operationContractAttribs[0] is AttributeInfoAttribute)
|
|
{
|
|
AttributeInfoAttribute attribInfoAttrib = operationContractAttribs[0] as AttributeInfoAttribute;
|
|
if (typeof(OperationContractAttribute).IsAssignableFrom(attribInfoAttrib.AttributeInfo.AttributeType))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
internal static List<Type> GetContracts(Type contractType)
|
|
{
|
|
List<Type> types = new List<Type>();
|
|
if (contractType.IsDefined(typeof(ServiceContractAttribute), false))
|
|
{
|
|
types.Add(contractType);
|
|
}
|
|
foreach (Type contract in contractType.GetInterfaces())
|
|
{
|
|
if (contract.IsDefined(typeof(ServiceContractAttribute), false))
|
|
{
|
|
types.Add(contract);
|
|
}
|
|
}
|
|
|
|
return types;
|
|
}
|
|
|
|
internal static SessionMode GetContractSessionMode(IServiceProvider serviceProvider, AttributeInfo attribInfo)
|
|
{
|
|
string propertyName = "SessionMode";
|
|
SessionMode sessionMode = SessionMode.Allowed;
|
|
if (!TryGetArgumentValueAs<SessionMode>(serviceProvider, attribInfo, propertyName, out sessionMode))
|
|
{
|
|
sessionMode = SessionMode.Allowed;
|
|
}
|
|
return sessionMode;
|
|
}
|
|
|
|
internal static object[] GetCustomAttributes(Type attributeType, Attribute[] attributes)
|
|
{
|
|
if (attributeType == null)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("attributeType");
|
|
}
|
|
|
|
ArrayList attributeList = new ArrayList();
|
|
|
|
foreach (Attribute currentAttribute in attributes)
|
|
{
|
|
if (attributeType.IsAssignableFrom(currentAttribute.GetType()))
|
|
{
|
|
attributeList.Add(currentAttribute);
|
|
}
|
|
}
|
|
|
|
return attributeList.ToArray();
|
|
}
|
|
|
|
internal static bool GetOperationAsyncPattern(IServiceProvider serviceProvider, AttributeInfo attribInfo)
|
|
{
|
|
string propertyName = "AsyncPattern";
|
|
bool isAsync = false;
|
|
if (!TryGetArgumentValueAs<bool>(serviceProvider, attribInfo, propertyName, out isAsync))
|
|
{
|
|
isAsync = false;
|
|
}
|
|
return isAsync;
|
|
}
|
|
|
|
internal static bool IsDefined(Type attributeType,
|
|
Attribute[] attributes)
|
|
{
|
|
if (attributeType == null)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("attributeType");
|
|
}
|
|
|
|
foreach (Attribute attribute in attributes)
|
|
{
|
|
if (attributeType.IsAssignableFrom(attribute.GetType()))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
internal static bool IsInitiatingOperationContract(IServiceProvider serviceProvider, AttributeInfo attribInfo)
|
|
{
|
|
string propertyName = "IsInitiating";
|
|
bool isInitiating = true;
|
|
if (!TryGetArgumentValueAs<bool>(serviceProvider, attribInfo, propertyName, out isInitiating))
|
|
{
|
|
isInitiating = true;
|
|
}
|
|
return isInitiating;
|
|
}
|
|
|
|
internal static void SetWorkflowOperationBehavior(ContractDescription contractDescription, ServiceDescriptionContext context)
|
|
{
|
|
if (contractDescription == null)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("contractDescription");
|
|
}
|
|
|
|
if (context == null)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
|
|
}
|
|
|
|
foreach (OperationDescription opDescription in contractDescription.Operations)
|
|
{
|
|
WorkflowOperationBehavior behavior = null;
|
|
KeyValuePair<Type, string> operationKey =
|
|
new KeyValuePair<Type, string>(opDescription.DeclaringContract.ContractType, opDescription.Name);
|
|
|
|
if (!context.WorkflowOperationBehaviors.TryGetValue(operationKey, out behavior))
|
|
{
|
|
behavior = new WorkflowOperationBehavior();
|
|
context.WorkflowOperationBehaviors.Add(operationKey, behavior);
|
|
behavior.CanCreateInstance = false;
|
|
}
|
|
|
|
if (opDescription.Behaviors.Find<WorkflowOperationBehavior>() != behavior)
|
|
{
|
|
opDescription.Behaviors.Remove(typeof(WorkflowOperationBehavior));
|
|
opDescription.Behaviors.Add(behavior);
|
|
}
|
|
}
|
|
}
|
|
|
|
private static string[] GetAttributePropertyNames(AttributeInfo attributeInfo)
|
|
{
|
|
if (attributeInfo == null)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("attributeInfo");
|
|
}
|
|
|
|
string[] argumentNames = null;
|
|
BindingFlags bindingFlags = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.NonPublic;
|
|
FieldInfo argumentNamesField = typeof(AttributeInfo).GetField("argumentNames", bindingFlags);
|
|
if (argumentNamesField != null)
|
|
{
|
|
argumentNames = argumentNamesField.GetValue(attributeInfo) as string[];
|
|
}
|
|
|
|
return argumentNames;
|
|
}
|
|
|
|
|
|
private static bool TryGetArgumentValueAs<T>(IServiceProvider serviceProvider, AttributeInfo attribInfo, string propertyName, out T propertyValue)
|
|
{
|
|
string[] argumentNames = GetAttributePropertyNames(attribInfo);
|
|
int argumentIndex = -1;
|
|
for (int index = 0; index < argumentNames.Length; index++)
|
|
{
|
|
// skip unnamed arguments these are constructor arguments
|
|
if (string.IsNullOrEmpty((argumentNames[index])))
|
|
{
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
if (argumentNames[index].Equals(propertyName))
|
|
{
|
|
argumentIndex = index;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (argumentIndex == -1)
|
|
{
|
|
propertyValue = default(T);
|
|
return false;
|
|
}
|
|
propertyValue = (T) attribInfo.GetArgumentValueAs(serviceProvider, argumentIndex, typeof(T));
|
|
return true;
|
|
}
|
|
}
|
|
}
|