示例#1
0
        /// <summary>
        /// Returns the Cadence workflow type name to be used for a workflow interface or
        /// implementation class.
        /// </summary>
        /// <param name="workflowType">The workflow interface or implementation type.</param>
        /// <param name="workflowAttribute">Specifies the <see cref="WorkflowAttribute"/>.</param>
        /// <returns>The type name.</returns>
        /// <remarks>
        /// <para>
        /// If <paramref name="workflowAttribute"/> is passed and <see cref="WorkflowAttribute.Name"/>
        /// is not <c>null</c> or empty, then the name specified in the attribute is returned.
        /// </para>
        /// <para>
        /// Otherwise, we'll return the fully qualified name of the workflow interface
        /// with the leadting "I" removed.
        /// </para>
        /// </remarks>
        internal static string GetWorkflowTypeName(Type workflowType, WorkflowAttribute workflowAttribute)
        {
            Covenant.Requires <ArgumentNullException>(workflowType != null, nameof(workflowType));

            if (workflowAttribute != null && !string.IsNullOrEmpty(workflowAttribute.Name))
            {
                return(workflowAttribute.Name);
            }

            if (workflowType.IsClass)
            {
                CadenceHelper.ValidateWorkflowImplementation(workflowType);

                workflowType = CadenceHelper.GetWorkflowInterface(workflowType);
            }
            else
            {
                CadenceHelper.ValidateWorkflowInterface(workflowType);
            }

            var fullName = workflowType.FullName;
            var name     = workflowType.Name;

            if (name.StartsWith("I") && name != "I")
            {
                // We're going to strip the leading "I" from the unqualified
                // type name (unless that's the only character).

                fullName  = fullName.Substring(0, fullName.Length - name.Length);
                fullName += name.Substring(1);
            }

            // We need to replace the "+" characters .NET uses for nested types into
            // "." so the result will be a valid C# type identifier.

            return(fullName.Replace('+', '.'));
        }
示例#2
0
        /// <summary>
        /// Returns the workflow type and method information for a workflow interface and
        /// an optional target method name.
        /// </summary>
        /// <param name="workflowInterface">The target workflow interface.</param>
        /// <param name="methodName">
        /// Optionally specifies the target method name (as specified in the <c>[WorkflowMethod]</c>
        /// attribiute tagging the workflow method within the interface.
        /// </param>
        /// <returns>The workflow type name for the workflow interface as well as the method information and attribute.</returns>
        /// <exception cref="ArgumentException">Thrown if target method does not exist.</exception>
        /// <remarks>
        /// <paramref name="methodName"/> is optional.  When this is passed as <c>null</c>
        /// or empty, the default workflow method will be targeted (if any).
        /// </remarks>
        internal static (string WorkflowTypeName, MethodInfo TargetMethod, WorkflowMethodAttribute MethodAttribute) GetWorkflowTarget(Type workflowInterface, string methodName = null)
        {
            Covenant.Requires <ArgumentNullException>(workflowInterface != null);

            CadenceHelper.ValidateWorkflowInterface(workflowInterface);

            var workflowAttribute = workflowInterface.GetCustomAttribute <WorkflowAttribute>();
            var methodAttribute   = (WorkflowMethodAttribute)null;
            var targetMethod      = (MethodInfo)null;

            if (string.IsNullOrEmpty(methodName))
            {
                // Look for the entrypoint method with a null or empty method name.

                foreach (var method in workflowInterface.GetMethods())
                {
                    methodAttribute = method.GetCustomAttribute <WorkflowMethodAttribute>();

                    if (methodAttribute != null)
                    {
                        if (string.IsNullOrEmpty(methodAttribute.Name))
                        {
                            targetMethod = method;
                            break;
                        }
                    }
                }
            }
            else
            {
                // Look for the entrypoint method with the matching method name.

                foreach (var method in workflowInterface.GetMethods())
                {
                    methodAttribute = method.GetCustomAttribute <WorkflowMethodAttribute>();

                    if (methodAttribute != null)
                    {
                        if (methodName == methodAttribute.Name)
                        {
                            targetMethod = method;
                            break;
                        }
                    }
                }
            }

            if (targetMethod == null)
            {
                throw new ArgumentException($"Workflow interface [{workflowInterface.FullName}] does not have a method tagged by [WorkflowMethod(Name = {methodName})].", nameof(workflowInterface));
            }

            var workflowTypeName = CadenceHelper.GetWorkflowTypeName(workflowInterface, workflowAttribute);

            if (!string.IsNullOrEmpty(methodAttribute.Name))
            {
                workflowTypeName += $"::{methodAttribute.Name}";
            }

            return(workflowTypeName, targetMethod, methodAttribute);
        }