/// <summary> /// Registers an activity implementation with Cadence. /// </summary> /// <typeparam name="TActivity">The <see cref="ActivityBase"/> derived class implementing the activity.</typeparam> /// <param name="activityTypeName"> /// Optionally specifies a custom activity type name that will be used /// for identifying the activity implementation in Cadence. This defaults /// to the fully qualified <typeparamref name="TActivity"/> 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 a different activity class has already been registered for <paramref name="activityTypeName"/>.</exception> /// <exception cref="ActivityWorkerStartedException"> /// Thrown if an activity worker has already been started for the client. You must /// register activity implementations before starting workers. /// </exception> /// <remarks> /// <note> /// Be sure to register all services you will be injecting into activities via /// <see cref="NeonHelper.ServiceContainer"/> before you call this as well as /// registering of your activity implementations before starting workers. /// </note> /// </remarks> public async Task RegisterActivityAsync <TActivity>(string activityTypeName = null, string domain = null) where TActivity : ActivityBase { await SyncContext.Clear; CadenceHelper.ValidateActivityImplementation(typeof(TActivity)); CadenceHelper.ValidateActivityTypeName(activityTypeName); EnsureNotDisposed(); if (activityWorkerStarted) { throw new ActivityWorkerStartedException(); } var activityType = typeof(TActivity); if (string.IsNullOrEmpty(activityTypeName)) { activityTypeName = CadenceHelper.GetActivityTypeName(activityType, activityType.GetCustomAttribute <ActivityAttribute>()); } await ActivityBase.RegisterAsync(this, activityType, activityTypeName, ResolveDomain(domain)); lock (registeredActivityTypes) { registeredActivityTypes.Add(CadenceHelper.GetActivityInterface(typeof(TActivity))); } }
/// <summary> /// Scans the assembly passed looking for activity implementations derived from /// <see cref="ActivityBase"/> and tagged by <see cref="ActivityAttribute"/> 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="ActivityAttribute"/> that are not /// derived from <see cref="ActivityBase"/>. /// </exception> /// <exception cref="InvalidOperationException">Thrown if one of the tagged classes conflict with an existing registration.</exception> /// <exception cref="ActivityWorkerStartedException"> /// Thrown if an activity worker has already been started for the client. You must /// register activity implementations before starting workers. /// </exception> /// <remarks> /// <note> /// Be sure to register all services you will be injecting into activities via /// <see cref="NeonHelper.ServiceContainer"/> before you call this as well as /// registering of your activity implementations before starting workers. /// </note> /// </remarks> public async Task RegisterAssemblyActivitiesAsync(Assembly assembly, string domain = null) { await SyncContext.Clear; Covenant.Requires <ArgumentNullException>(assembly != null, nameof(assembly)); EnsureNotDisposed(); if (activityWorkerStarted) { throw new ActivityWorkerStartedException(); } foreach (var type in assembly.GetTypes().Where(type => type.IsClass)) { var activityAttribute = type.GetCustomAttribute <ActivityAttribute>(); if (activityAttribute != null && activityAttribute.AutoRegister) { var activityTypeName = CadenceHelper.GetActivityTypeName(type, activityAttribute); await ActivityBase.RegisterAsync(this, type, activityTypeName, ResolveDomain(domain)); lock (registeredActivityTypes) { registeredActivityTypes.Add(CadenceHelper.GetActivityInterface(type)); } } } }