/// <summary> /// Finishes the setup of the bus, using default implementations for the options that have not explicitly been set. /// The only requirement, is that you must call <see cref="Transport"/> and select which transport to use - everything /// else can run with a default option. It should be noted though, that several of the defaults (e.g. in-mem persistence /// options for saga storage, subscriptions, and timeouts) are not meant for production use, and should probably be /// replaced by something that is actually persistent. /// </summary> public IBus Start() { VerifyRequirements(); PossiblyRegisterDefault <IRebusLoggerFactory>(c => new ConsoleLoggerFactory(true)); PossiblyRegisterDefault <IAsyncTaskFactory>(c => new TplAsyncTaskFactory(c.Get <IRebusLoggerFactory>())); PossiblyRegisterDefault <IRouter>(c => { var rebusLoggerFactory = c.Get <IRebusLoggerFactory>(); return(new TypeBasedRouter(rebusLoggerFactory)); }); PossiblyRegisterDefault <ISubscriptionStorage>(c => new InMemorySubscriptionStorage()); PossiblyRegisterDefault <ISagaStorage>(c => new InMemorySagaStorage()); PossiblyRegisterDefault <ISerializer>(c => new JsonSerializer()); PossiblyRegisterDefault <IPipelineInvoker>(c => new DefaultPipelineInvoker()); PossiblyRegisterDefault <IBackoffStrategy>(c => new SimpleConstantPollingBackoffStrategy()); PossiblyRegisterDefault <IWorkerFactory>(c => { var transport = c.Get <ITransport>(); var pipeline = c.Get <IPipeline>(); var pipelineInvoker = c.Get <IPipelineInvoker>(); var backoffStrategy = c.Get <IBackoffStrategy>(); var rebusLoggerFactory = c.Get <IRebusLoggerFactory>(); return(new ThreadWorkerFactory(transport, pipeline, pipelineInvoker, _options.MaxParallelism, backoffStrategy, rebusLoggerFactory)); }); PossiblyRegisterDefault <IErrorTracker>(c => { var settings = c.Get <SimpleRetryStrategySettings>(); var rebusLoggerFactory = c.Get <IRebusLoggerFactory>(); var asyncTaskFactory = c.Get <IAsyncTaskFactory>(); return(new InMemErrorTracker(settings.MaxDeliveryAttempts, rebusLoggerFactory, asyncTaskFactory)); }); PossiblyRegisterDefault <IRetryStrategy>(c => { var transport = c.Get <ITransport>(); var simpleRetryStrategySettings = c.Get <SimpleRetryStrategySettings>(); var errorTracker = c.Get <IErrorTracker>(); var rebusLoggerFactory = c.Get <IRebusLoggerFactory>(); return(new SimpleRetryStrategy(transport, simpleRetryStrategySettings, errorTracker, rebusLoggerFactory)); }); PossiblyRegisterDefault(c => new SimpleRetryStrategySettings()); PossiblyRegisterDefault <ITimeoutManager>(c => new InMemoryTimeoutManager()); PossiblyRegisterDefault(c => { var transport = c.Get <ITransport>(); var timeoutManager = c.Get <ITimeoutManager>(); var rebusLoggerFactory = c.Get <IRebusLoggerFactory>(); var asyncTaskFactory = c.Get <IAsyncTaskFactory>(); return(new HandleDeferredMessagesStep(timeoutManager, transport, _options, rebusLoggerFactory, asyncTaskFactory)); }); PossiblyRegisterDefault(c => c.Get <IRetryStrategy>().GetRetryStep()); PossiblyRegisterDefault <IPipeline>(c => { var serializer = c.Get <ISerializer>(); var transport = c.Get <ITransport>(); var rebusLoggerFactory = c.Get <IRebusLoggerFactory>(); return(new DefaultPipeline() .OnReceive(c.Get <IRetryStrategyStep>()) .OnReceive(c.Get <HandleDeferredMessagesStep>()) .OnReceive(new DeserializeIncomingMessageStep(serializer)) .OnReceive(new ActivateHandlersStep(c.Get <IHandlerActivator>())) .OnReceive(new LoadSagaDataStep(c.Get <ISagaStorage>(), rebusLoggerFactory)) .OnReceive(new DispatchIncomingMessageStep()) .OnSend(new AssignGuidMessageIdStep()) .OnSend(new AssignReturnAddressStep(transport)) .OnSend(new AssignDateTimeOffsetHeader()) .OnSend(new FlowCorrelationIdStep()) .OnSend(new AutoHeadersOutgoingStep()) .OnSend(new AssignTypeHeaderStep()) .OnSend(new SerializeOutgoingMessageStep(serializer)) .OnSend(new SendOutgoingMessageStep(transport, rebusLoggerFactory))); }); RegisterDecorator <IPipeline>(c => new PipelineCache(c.Get <IPipeline>())); // configuration hack - keep these two bad boys around to have them available at the last moment before returning the built bus instance... IContainerAdapter containerAdapter = null; Action startAction = null; PossiblyRegisterDefault <IBus>(c => { var bus = new RebusBus( c.Get <IWorkerFactory>(), c.Get <IRouter>(), c.Get <ITransport>(), c.Get <IPipeline>(), c.Get <IPipelineInvoker>(), c.Get <ISubscriptionStorage>(), _options, c.Get <IRebusLoggerFactory>()); bus.Disposed += () => { var disposableInstances = c.GetTrackedInstancesOf <IDisposable>().Reverse(); foreach (var disposableInstance in disposableInstances) { disposableInstance.Dispose(); } }; var initializableInstances = c.GetTrackedInstancesOf <IInitializable>(); foreach (var initializableInstance in initializableInstances) { initializableInstance.Initialize(); } if (_injectionist.Has <IContainerAdapter>()) { containerAdapter = c.Get <IContainerAdapter>(); } startAction = () => bus.Start(_options.NumberOfWorkers); return(bus); }); _injectionist.Decorate <IHandlerActivator>(c => { var handlerActivator = c.Get <IHandlerActivator>(); var subscriptionStorage = c.Get <ISubscriptionStorage>(); var internalHandlersContributor = new InternalHandlersContributor(handlerActivator, subscriptionStorage); return(internalHandlersContributor); }); var busInstance = _injectionist.Get <IBus>(); containerAdapter?.SetBus(busInstance); startAction?.Invoke(); _hasBeenStarted = true; return(busInstance); }