// Helper to invoke any handler config attributes on this handler type or its base classes. private static void InvokeAttributesOnHandlerType(CommandHandlerDescriptor descriptor, Type type) { Contract.Requires(descriptor != null); if (type == null) { return; } // Initialize base class before derived classes (same order as ctors). InvokeAttributesOnHandlerType(descriptor, type.BaseType); // Check for attribute object[] attrs = type.GetCustomAttributes(inherit: false); for (int i = 0; i < attrs.Length; i++) { object attr = attrs[i]; IHandlerConfiguration handlerConfig = attr as IHandlerConfiguration; if (handlerConfig != null) { ProcessorConfiguration originalConfig = descriptor.Configuration; CommandHandlerSettings settings = new CommandHandlerSettings(originalConfig); handlerConfig.Initialize(settings, descriptor); descriptor.Configuration = ProcessorConfiguration.ApplyHandlerSettings(settings, originalConfig); } } }
private ProcessorConfiguration(ProcessorConfiguration configuration, CommandHandlerSettings settings) { Contract.Requires(configuration != null); Contract.Requires(settings != null); this.filters = configuration.Filters; this.dependencyResolver = configuration.DependencyResolver; this.DefaultHandlerLifetime = configuration.DefaultHandlerLifetime; this.Properties = configuration.Properties; this.CommandBroker = configuration.CommandBroker; // per-handler settings this.Services = settings.Services; this.AbortOnInvalidCommand = settings.AbortOnInvalidCommand; this.ServiceProxyCreationEnabled = configuration.ServiceProxyCreationEnabled; // Use the original configuration's initializer so that its Initialize() // will perform the same logic on this clone as on the original. this.Initializer = configuration.Initializer; }
/// <summary> /// Enables message queuing. /// </summary> /// <param name="configuration">The <see cref="ProcessorConfiguration"/>.</param> /// <param name="degreeOfParallelism">The maximum degree of parallelism.</param> /// <param name="sender">The <see cref="ICommandSender"/> used to send commands.</param> /// <param name="receiver">The <see cref="ICommandReceiver"/> used to receive commands.</param> public static void EnableMessageQueuing(this ProcessorConfiguration configuration, int degreeOfParallelism, ICommandSender sender, ICommandReceiver receiver) { if (configuration == null) { throw Error.ArgumentNull("configuration"); } var innerWorker = configuration.Services.GetCommandWorker(); configuration.Services.Replace(typeof(ICommandWorker), new CommandQueueWorker(innerWorker)); configuration.Services.Replace(typeof(ICommandSender), sender); configuration.Services.Replace(typeof(ICommandReceiver), receiver); configuration.RegisterForDispose(sender as IDisposable); if (!object.ReferenceEquals(sender, receiver)) { configuration.RegisterForDispose(receiver as IDisposable); } Action<ProcessorConfiguration> defaultInitializer = configuration.Initializer; configuration.Initializer = originalConfig => { MessageProcessor processor = null; try { CommandHandlerSettings settings = new CommandHandlerSettings(originalConfig); settings.Services.Replace(typeof(ICommandWorker), innerWorker); var config = ProcessorConfiguration.ApplyHandlerSettings(settings, originalConfig); config.Initializer = defaultInitializer; processor = new MessageProcessor(config); var commandReceiver = originalConfig.Services.GetCommandReceiver(); originalConfig.CommandBroker = new CommandRunner(processor, commandReceiver, degreeOfParallelism); originalConfig.RegisterForDispose(processor); processor = null; } finally { if (processor != null) { processor.Dispose(); } } defaultInitializer(originalConfig); }; }
internal static ProcessorConfiguration ApplyHandlerSettings(CommandHandlerSettings settings, ProcessorConfiguration configuration) { Contract.Requires(settings != null); Contract.Requires(configuration != null); if (!settings.IsServiceCollectionInitialized) { return configuration; } return new ProcessorConfiguration(configuration, settings); }