示例#1
0
        /// <summary>
        /// Returns the Cadence activity type name to be used for a activity interface or
        /// implementation class.
        /// </summary>
        /// <param name="activityType">The activity interface or implementation type.</param>
        /// <param name="activityAttribute">Specifies the <see cref="ActivityAttribute"/>.</param>
        /// <returns>The type name.</returns>
        /// <remarks>
        /// <para>
        /// If <paramref name="activityAttribute"/> is passed and <see cref="ActivityAttribute.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 activity interface
        /// with the leadting "I" removed.
        /// </para>
        /// </remarks>
        internal static string GetActivityTypeName(Type activityType, ActivityAttribute activityAttribute)
        {
            Covenant.Requires <ArgumentNullException>(activityType != null, nameof(activityType));

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

            if (activityType.IsClass)
            {
                CadenceHelper.ValidateActivityImplementation(activityType);

                activityType = CadenceHelper.GetActivityInterface(activityType);
            }
            else
            {
                CadenceHelper.ValidateActivityInterface(activityType);
            }

            var fullName = activityType.FullName;
            var name     = activityType.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 activity type and method information for an activity interface and
        /// an optional target method name.
        /// </summary>
        /// <param name="activityInterface">The target activity interface.</param>
        /// <param name="methodName">
        /// Optionally specifies the target method name (as specified in the <c>[ActivityMethod]</c>
        /// attribiute tagging the activity method within the interface.
        /// </param>
        /// <returns>The activity type name for the activity 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 activity method will be targeted (if any).
        /// </remarks>
        internal static (string ActivityTypeName, MethodInfo TargetMethod, ActivityMethodAttribute MethodAttribute) GetActivityTarget(Type activityInterface, string methodName = null)
        {
            Covenant.Requires <ArgumentNullException>(activityInterface != null);

            CadenceHelper.ValidateActivityInterface(activityInterface);

            var activityAttribute = activityInterface.GetCustomAttribute <ActivityAttribute>();
            var methodAttribute   = (ActivityMethodAttribute)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 activityInterface.GetMethods())
                {
                    methodAttribute = method.GetCustomAttribute <ActivityMethodAttribute>();

                    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 activityInterface.GetMethods())
                {
                    methodAttribute = method.GetCustomAttribute <ActivityMethodAttribute>();

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

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

            var activityTypeName = CadenceHelper.GetActivityTypeName(activityInterface, activityAttribute);

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

            return(activityTypeName, targetMethod, methodAttribute);
        }