//--------------------------------------------------------------------- // Public Cadence workflow related operations. /// <summary> /// Registers a workflow implementation with Cadence. /// </summary> /// <typeparam name="TWorkflow">The <see cref="WorkflowBase"/> derived class implementing the workflow.</typeparam> /// <param name="workflowTypeName"> /// Optionally specifies a custom workflow type name that will be used /// for identifying the workflow implementation in Cadence. This defaults /// to the fully qualified <typeparamref name="TWorkflow"/> type name. /// </param> /// <param name="domain">Optionally overrides the default client domain.</param> /// <returns>The tracking <see cref="Task"/>.</returns> /// <exception cref="InvalidOperationException">Thrown if another workflow class has already been registered for <paramref name="workflowTypeName"/>.</exception> /// <exception cref="WorkflowWorkerStartedException"> /// Thrown if a workflow worker has already been started for the client. You must /// register workflow implementations before starting workers. /// </exception> /// <remarks> /// <note> /// Be sure to register all of your workflow implementations before starting workers. /// </note> /// </remarks> public async Task RegisterWorkflowAsync <TWorkflow>(string workflowTypeName = null, string domain = null) where TWorkflow : WorkflowBase { await SyncContext.ClearAsync; CadenceHelper.ValidateWorkflowImplementation(typeof(TWorkflow)); CadenceHelper.ValidateWorkflowTypeName(workflowTypeName); EnsureNotDisposed(); if (workflowWorkerStarted) { throw new WorkflowWorkerStartedException(); } var workflowType = typeof(TWorkflow); if (string.IsNullOrEmpty(workflowTypeName)) { workflowTypeName = CadenceHelper.GetWorkflowTypeName(workflowType, workflowType.GetCustomAttribute <WorkflowAttribute>()); } await WorkflowBase.RegisterAsync(this, workflowType, workflowTypeName, ResolveDomain(domain)); lock (registeredWorkflowTypes) { registeredWorkflowTypes.Add(CadenceHelper.GetWorkflowInterface(typeof(TWorkflow))); } }
/// <summary> /// Scans the assembly passed looking for workflow implementations derived from /// <see cref="WorkflowBase"/> and tagged by <see cref="WorkflowAttribute"/> with /// <see cref="WorkflowAttribute.AutoRegister"/> set to <c>true</c> and registers /// them with Cadence. /// </summary> /// <param name="assembly">The target assembly.</param> /// <param name="domain">Optionally overrides the default client domain.</param> /// <returns>The tracking <see cref="Task"/>.</returns> /// <exception cref="TypeLoadException"> /// Thrown for types tagged by <see cref="WorkflowAttribute"/> that are not /// derived from <see cref="WorkflowBase"/>. /// </exception> /// <exception cref="InvalidOperationException">Thrown if one of the tagged classes conflict with an existing registration.</exception> /// <exception cref="WorkflowWorkerStartedException"> /// Thrown if a workflow worker has already been started for the client. You must /// register workflow implementations before starting workers. /// </exception> /// <remarks> /// <note> /// Be sure to register all of your workflow implementations before starting workers. /// </note> /// </remarks> public async Task RegisterAssemblyWorkflowsAsync(Assembly assembly, string domain = null) { await SyncContext.ClearAsync; Covenant.Requires <ArgumentNullException>(assembly != null, nameof(assembly)); EnsureNotDisposed(); foreach (var type in assembly.GetTypes().Where(t => t.IsClass)) { var workflowAttribute = type.GetCustomAttribute <WorkflowAttribute>(); if (workflowAttribute != null && workflowAttribute.AutoRegister) { var workflowTypeName = CadenceHelper.GetWorkflowTypeName(type, workflowAttribute); await WorkflowBase.RegisterAsync(this, type, workflowTypeName, ResolveDomain(domain)); lock (registeredWorkflowTypes) { registeredWorkflowTypes.Add(CadenceHelper.GetWorkflowInterface(type)); } } } }