public void HasDefaultRegistrations() { var container = new Injectionist(); var _ = new ConfigDriveBuilder(container); Assert.IsType <YamlSerializer>(container.Get <IYamlSerializer>().Instance); Assert.IsType <UserDataSerializer>(container.Get <IUserDataSerializer>().Instance); }
public IToposProducer Create() { ToposConfigurerHelpers.RegisterCommonServices(_injectionist); _injectionist.PossiblyRegisterDefault <ITopicMapper>(c => new SimpleTopicMapper()); _injectionist.Register <IToposProducer>(c => { var messageSerializer = c.Get <IMessageSerializer>(); var topicMapper = c.Get <ITopicMapper>(); var producerImplementation = c.Get <IProducerImplementation>(errorMessage: "Røvhul"); var loggerFactory = c.Get <ILoggerFactory>(); var defaultToposProducer = new DefaultToposProducer( messageSerializer, topicMapper, producerImplementation, loggerFactory ); defaultToposProducer.Disposing += () => { foreach (var instance in c.TrackedInstances.OfType <IDisposable>().Reverse()) { instance.Dispose(); } }; return(defaultToposProducer); }); var resolutionResult = _injectionist.Get <IToposProducer>(); return(resolutionResult.Instance); }
public IToposConsumer Create() { ToposConfigurerHelpers.RegisterCommonServices(_injectionist); _injectionist.PossiblyRegisterDefault <IConsumerDispatcher>(c => { var loggerFactory = c.Get <ILoggerFactory>(); var messageSerializer = c.Get <IMessageSerializer>(); var handlers = c.Get <Handlers>(errorMessage: @"Failing to get the handlers is a sign that the consumer has not had any handlers configured. Please remember to configure at least one handler by invoking the .Handle(..) configurer like this: Configure.Consumer(...) .Handle(async (messages, cancellationToken) => { // handle messages }) .Start() "); var positionManager = c.Get <IPositionManager>(errorMessage: @"The consumer dispatcher needs access to a positions manager, so it can store a 'high water mark' position for each topic/partition. It can be configured by invoking the .Positions(..) configurer like this: Configure.Consumer(...) .Positions(p => p.StoreIn(...)) .Start() "); return(new DefaultConsumerDispatcher(loggerFactory, messageSerializer, handlers, positionManager)); }); _injectionist.Register <IToposConsumer>(c => { var toposConsumerImplementation = c.Get <IConsumerImplementation>(); var defaultToposConsumer = new DefaultToposConsumer(toposConsumerImplementation); defaultToposConsumer.Disposing += () => { foreach (var instance in c.TrackedInstances.OfType <IDisposable>().Reverse()) { instance.Dispose(); } }; return(defaultToposConsumer); }); var resolutionResult = _injectionist.Get <IToposConsumer>(); foreach (var initializable in resolutionResult.TrackedInstances.OfType <IInitializable>()) { initializable.Initialize(); } return(resolutionResult.Instance); }
public void NoCloudDataSourceRegistered() { var container = new Injectionist(); var builder = new ConfigDriveBuilder(container); builder.NoCloud(new NoCloudConfigDriveMetaData()); Assert.IsType <NoCloudDataSource>(container.Get <IConfigDriveDataSource>().Instance); }
public IConfigDrive Build() { if (!_container.Has <IConfigDriveDataSource>()) { throw new CloudInitConfigurationException("No data source has been configured"); } return(_container.Get <IConfigDrive>().Instance); }
public void WithCustomRegistration() { var container = new Injectionist(); var builder = new ConfigDriveBuilder(container); var customType = new CustomType(); builder.With(ctx => customType); Assert.Equal(customType, container.Get <CustomType>().Instance); }
public void InjectedWhateverWithWhateverInsideIsProperlyDisposed() { var injectionist = new Injectionist(); var eventTracker = new EventTracker(); injectionist.Register(c => { var fakeBus = new FakeBus(c.Get <Disposable1>(), c.Get <EventTracker>()); fakeBus.FakeBusDisposed += () => { foreach (var disposable in c.GetTrackedInstancesOf <IDisposable>().Reverse()) { disposable.Dispose(); } }; foreach (var disposable in c.GetTrackedInstancesOf <IInitializable>()) { disposable.Initialize(); } return(fakeBus); }); injectionist.Register(c => new Disposable1(c.Get <Disposable2>(), c.Get <EventTracker>())); injectionist.Register(c => new Disposable2(c.Get <EventTracker>())); injectionist.Register(c => eventTracker); using (var bus = injectionist.Get <FakeBus>()) { Console.WriteLine("Using the bus...."); Console.WriteLine("Disposing it"); } Console.WriteLine(@"Here's what happened: {0}", string.Join(Environment.NewLine, eventTracker.Events.Select(e => "- " + e))); Assert.That(eventTracker.Events, Is.EqualTo(new[] { "EventTracker initialized", "Disposable2 initialized", "Disposable1 initialized", "Disposable1 disposed", "Disposable2 disposed", "EventTracker disposed", "FakeBus disposed", })); }
public void InjectedWhateverWithWhateverInsideIsProperlyDisposed() { var injectionist = new Injectionist(); var eventTracker = new EventTracker(); injectionist.Register(c => { var fakeBus = new FakeBus(c.Get<Disposable1>(), c.Get<EventTracker>()); fakeBus.FakeBusDisposed += () => { foreach (var disposable in c.GetTrackedInstancesOf<IDisposable>().Reverse()) { disposable.Dispose(); } }; foreach (var disposable in c.GetTrackedInstancesOf<IInitializable>()) { disposable.Initialize(); } return fakeBus; }); injectionist.Register(c => new Disposable1(c.Get<Disposable2>(), c.Get<EventTracker>())); injectionist.Register(c => new Disposable2(c.Get<EventTracker>())); injectionist.Register(c => eventTracker); using (var bus = injectionist.Get<FakeBus>()) { Console.WriteLine("Using the bus...."); Console.WriteLine("Disposing it"); } Console.WriteLine(@"Here's what happened: {0}", string.Join(Environment.NewLine, eventTracker.Events.Select(e => "- " + e))); Assert.That(eventTracker.Events, Is.EqualTo(new[] { "EventTracker initialized", "Disposable2 initialized", "Disposable1 initialized", "Disposable1 disposed", "Disposable2 disposed", "EventTracker disposed", "FakeBus disposed", })); }
public IToposProducer Create() { ToposConfigurerHelpers.RegisterCommonServices(_injectionist); _injectionist.Register <IToposProducer>(c => { var messageSerializer = c.Get <IMessageSerializer>(); var producerImplementation = c.Get <IProducerImplementation>(errorMessage: "Failing to get the producer implementation can be caused by a missing registration of IProducerImplementation"); var loggerFactory = c.Get <ILoggerFactory>(); var defaultToposProducer = new DefaultToposProducer( messageSerializer, producerImplementation, loggerFactory ); defaultToposProducer.Disposing += () => { foreach (var instance in c.TrackedInstances.OfType <IDisposable>().Reverse()) { instance.Dispose(); } }; return(defaultToposProducer); }); var resolutionResult = _injectionist.Get <IToposProducer>(); foreach (var initializable in resolutionResult.TrackedInstances.OfType <IInitializable>()) { initializable.Initialize(); } return(resolutionResult.Instance); }
/// <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() { #if HAS_CONFIGURATION_MANAGER // force the silly configuration subsystem to initialize itself as a service to users, thus // avoiding the oft-encountered stupid Entity Framework initialization exception // complaining that something in Rebus' transaction context is not serializable System.Configuration.ConfigurationManager.GetSection("system.xml/xmlReader"); // if you want to know more about this issue, check this out: https://docs.microsoft.com/en-us/dotnet/framework/migration-guide/mitigation-deserialization-of-objects-across-app-domains #endif VerifyRequirements(); _injectionist.Register(c => _options); _injectionist.Register(c => new CancellationTokenSource()); _injectionist.Register(c => c.Get <CancellationTokenSource>().Token); PossiblyRegisterDefault <IRebusLoggerFactory>(c => new ConsoleLoggerFactory(true)); PossiblyRegisterDefault <IRebusTime>(c => new DefaultRebusTime()); //PossiblyRegisterDefault<IAsyncTaskFactory>(c => new TimerAsyncTaskFactory(c.Get<IRebusLoggerFactory>())); PossiblyRegisterDefault <IAsyncTaskFactory>(c => { var rebusLoggerFactory = c.Get <IRebusLoggerFactory>(); return(new TplAsyncTaskFactory(rebusLoggerFactory)); }); PossiblyRegisterDefault <IRouter>(c => { var rebusLoggerFactory = c.Get <IRebusLoggerFactory>(); return(new TypeBasedRouter(rebusLoggerFactory)); }); PossiblyRegisterDefault <ISubscriptionStorage>(c => new DisabledSubscriptionStorage()); PossiblyRegisterDefault <ISagaStorage>(c => new DisabledSagaStorage()); PossiblyRegisterDefault <ITimeoutManager>(c => new DisabledTimeoutManager()); PossiblyRegisterDefault <ISerializer>(c => new JsonSerializer()); PossiblyRegisterDefault <IPipelineInvoker>(c => { var pipeline = c.Get <IPipeline>(); return(new DefaultPipelineInvokerNew(pipeline)); }); PossiblyRegisterDefault <IBackoffStrategy>(c => { var backoffTimes = new[] { // 10 s Enumerable.Repeat(TimeSpan.FromMilliseconds(100), 10), // on and on Enumerable.Repeat(TimeSpan.FromMilliseconds(250), 1) }; return(new DefaultBackoffStrategy(backoffTimes.SelectMany(e => e))); }); PossiblyRegisterDefault <IWorkerFactory>(c => { var transport = c.Get <ITransport>(); var rebusLoggerFactory = c.Get <IRebusLoggerFactory>(); var pipelineInvoker = c.Get <IPipelineInvoker>(); var options = c.Get <Options>(); var busLifetimeEvents = c.Get <BusLifetimeEvents>(); var backoffStrategy = c.Get <IBackoffStrategy>(); return(new ThreadPoolWorkerFactory(transport, rebusLoggerFactory, pipelineInvoker, options, c.Get <RebusBus>, busLifetimeEvents, backoffStrategy)); }); //PossiblyRegisterDefault<IWorkerFactory>(c => //{ // var transport = c.Get<ITransport>(); // var loggerFactory = c.Get<IRebusLoggerFactory>(); // var pipelineInvoker = c.Get<IPipelineInvoker>(); // var options = c.Get<Options>(); // var busLifetimeEvents = c.Get<BusLifetimeEvents>(); // var backoffStrategy = c.Get<IBackoffStrategy>(); // return new TplWorkerFactory(transport, loggerFactory, pipelineInvoker, options, c.Get<RebusBus>, busLifetimeEvents, backoffStrategy); //}); PossiblyRegisterDefault <IErrorTracker>(c => { var transport = c.Get <ITransport>(); var settings = c.Get <SimpleRetryStrategySettings>(); var rebusLoggerFactory = c.Get <IRebusLoggerFactory>(); var asyncTaskFactory = c.Get <IAsyncTaskFactory>(); var rebusTime = c.Get <IRebusTime>(); return(new InMemErrorTracker(settings, rebusLoggerFactory, asyncTaskFactory, transport, rebusTime)); }); PossiblyRegisterDefault <IErrorHandler>(c => { var settings = c.Get <SimpleRetryStrategySettings>(); var transport = c.Get <ITransport>(); var rebusLoggerFactory = c.Get <IRebusLoggerFactory>(); return(new PoisonQueueErrorHandler(settings, transport, rebusLoggerFactory)); }); PossiblyRegisterDefault <IFailFastChecker>(c => new FailFastChecker()); PossiblyRegisterDefault <IRetryStrategy>(c => { var simpleRetryStrategySettings = c.Get <SimpleRetryStrategySettings>(); var errorTracker = c.Get <IErrorTracker>(); var errorHandler = c.Get <IErrorHandler>(); return(new SimpleRetryStrategy(simpleRetryStrategySettings, errorTracker, errorHandler)); }); PossiblyRegisterDefault(c => new SimpleRetryStrategySettings()); 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>(); var options = c.Get <Options>(); var rebusTime = c.Get <IRebusTime>(); return(new DefaultPipeline() .OnReceive(c.Get <IRetryStrategyStep>()) .OnReceive(new FailFastStep(c.Get <IErrorTracker>(), c.Get <IFailFastChecker>())) .OnReceive(c.Get <HandleDeferredMessagesStep>()) .OnReceive(new HydrateIncomingMessageStep(c.Get <IDataBus>())) .OnReceive(new DeserializeIncomingMessageStep(serializer)) .OnReceive(new HandleRoutingSlipsStep(transport, serializer)) .OnReceive(new ActivateHandlersStep(c.Get <IHandlerActivator>())) .OnReceive(new LoadSagaDataStep(c.Get <ISagaStorage>(), rebusLoggerFactory)) .OnReceive(new DispatchIncomingMessageStep(rebusLoggerFactory)) .OnSend(new AssignDefaultHeadersStep(transport, rebusTime, options.DefaultReturnAddressOrNull)) .OnSend(new FlowCorrelationIdStep()) .OnSend(new AutoHeadersOutgoingStep()) .OnSend(new SerializeOutgoingMessageStep(serializer)) .OnSend(new ValidateOutgoingMessageStep()) .OnSend(new SendOutgoingMessageStep(transport, rebusLoggerFactory))); }); RegisterDecorator <IPipeline>(c => new PipelineCache(c.Get <IPipeline>())); PossiblyRegisterDefault(c => new BusLifetimeEvents()); PossiblyRegisterDefault <IDataBus>(c => new DisabledDataBus()); PossiblyRegisterDefault <ITopicNameConvention>(c => new DefaultTopicNameConvention()); // configuration hack - keep these two bad boys around to have them available at the last moment before returning the built bus instance... Action startAction = null; PossiblyRegisterDefault(c => new RebusBus( c.Get <IWorkerFactory>(), c.Get <IRouter>(), c.Get <ITransport>(), c.Get <IPipelineInvoker>(), c.Get <ISubscriptionStorage>(), _options, c.Get <IRebusLoggerFactory>(), c.Get <BusLifetimeEvents>(), c.Get <IDataBus>(), c.Get <ITopicNameConvention>(), c.Get <IRebusTime>() )); // since an error during resolution does not give access to disposable instances, we need to do this var disposableInstancesTrackedFromInitialResolution = new ConcurrentStack <IDisposable>(); PossiblyRegisterDefault <IBus>(c => { try { var bus = c.Get <RebusBus>(); var cancellationTokenSource = c.Get <CancellationTokenSource>(); bus.Disposed += () => { cancellationTokenSource.Cancel(); var disposableInstances = c.TrackedInstances.OfType <IDisposable>().Reverse(); foreach (var disposableInstance in disposableInstances) { disposableInstance.Dispose(); } }; var initializableInstances = c.TrackedInstances.OfType <IInitializable>(); foreach (var initializableInstance in initializableInstances) { initializableInstance.Initialize(); } // and then we set the startAction startAction = () => bus.Start(_options.NumberOfWorkers); return(bus); } catch { // stash'em here quick! foreach (var disposable in c.TrackedInstances.OfType <IDisposable>()) { disposableInstancesTrackedFromInitialResolution.Push(disposable); } throw; } }); _injectionist.Decorate <IHandlerActivator>(c => { var handlerActivator = c.Get <IHandlerActivator>(); var subscriptionStorage = c.Get <ISubscriptionStorage>(); var internalHandlersContributor = new InternalHandlersContributor(handlerActivator, subscriptionStorage); return(internalHandlersContributor); }); _injectionist.Decorate <ISerializer>(c => { var serializer = c.Get <ISerializer>(); var zipper = new Zipper(); var unzippingSerializerDecorator = new UnzippingSerializerDecorator(serializer, zipper); return(unzippingSerializerDecorator); }); try { var busResolutionResult = _injectionist.Get <IBus>(); var busInstance = busResolutionResult.Instance; // if there is a container adapter among the tracked instances, hand it the bus instance var containerAdapter = busResolutionResult.TrackedInstances .OfType <IContainerAdapter>() .FirstOrDefault(); containerAdapter?.SetBus(busInstance); // and NOW we are ready to start the bus if there is a startAction startAction?.Invoke(); _hasBeenStarted = true; return(busInstance); } catch { while (disposableInstancesTrackedFromInitialResolution.TryPop(out var disposable)) { try { disposable.Dispose(); } catch { } //< disposables must never throw, but sometimes they do } throw; } }
/// <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 <IRouter>(c => new TypeBasedRouter()); PossiblyRegisterDefault <ISubscriptionStorage>(c => new InMemorySubscriptionStorage()); PossiblyRegisterDefault <ISagaStorage>(c => new InMemorySagaStorage()); PossiblyRegisterDefault <ISerializer>(c => new JsonSerializer()); PossiblyRegisterDefault <IPipelineInvoker>(c => new DefaultPipelineInvoker()); PossiblyRegisterDefault <IWorkerFactory>(c => { var transport = c.Get <ITransport>(); var pipeline = c.Get <IPipeline>(); var pipelineInvoker = c.Get <IPipelineInvoker>(); return(new ThreadWorkerFactory(transport, pipeline, pipelineInvoker, _options.MaxParallelism)); }); PossiblyRegisterDefault <IRetryStrategy>(c => { var transport = c.Get <ITransport>(); var simpleRetryStrategySettings = c.Get <SimpleRetryStrategySettings>(); return(new SimpleRetryStrategy(transport, simpleRetryStrategySettings)); }); PossiblyRegisterDefault(c => new SimpleRetryStrategySettings()); PossiblyRegisterDefault <ITimeoutManager>(c => new InMemoryTimeoutManager()); PossiblyRegisterDefault(c => { var transport = c.Get <ITransport>(); var timeoutManager = c.Get <ITimeoutManager>(); return(new HandleDeferredMessagesStep(timeoutManager, transport)); }); PossiblyRegisterDefault(c => c.Get <IRetryStrategy>().GetRetryStep()); PossiblyRegisterDefault <IPipeline>(c => new DefaultPipeline() .OnReceive(c.Get <IRetryStrategyStep>()) .OnReceive(c.Get <HandleDeferredMessagesStep>()) .OnReceive(new DeserializeIncomingMessageStep(c.Get <ISerializer>())) .OnReceive(new ActivateHandlersStep(c.Get <IHandlerActivator>())) .OnReceive(new LoadSagaDataStep(c.Get <ISagaStorage>())) .OnReceive(new DispatchIncomingMessageStep()) .OnSend(new AssignGuidMessageIdStep()) .OnSend(new AssignReturnAddressStep(c.Get <ITransport>())) .OnSend(new AssignDateTimeOffsetHeader()) .OnSend(new FlowCorrelationIdStep()) .OnSend(new SerializeOutgoingMessageStep(c.Get <ISerializer>())) .OnSend(new SendOutgoingMessageStep(c.Get <ITransport>())) ); RegisterDecorator <IPipeline>(c => new PipelineCache(c.Get <IPipeline>())); 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>()); 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>()) { c.Get <IContainerAdapter>().SetBus(bus); } bus.Start(_options.NumberOfWorkers); return(bus); }); _injectionist.Register <IHandlerActivator>(c => { var handlerActivator = c.Get <IHandlerActivator>(); var subscriptionStorage = c.Get <ISubscriptionStorage>(); var internalHandlersContributor = new InternalHandlersContributor(handlerActivator, subscriptionStorage); return(internalHandlersContributor); }, isDecorator: true); var busInstance = _injectionist.Get <IBus>(); return(busInstance); }
/// <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(); _injectionist.Register(c => _options); PossiblyRegisterDefault <IRebusLoggerFactory>(c => new ConsoleLoggerFactory(true)); //PossiblyRegisterDefault<IAsyncTaskFactory>(c => new TimerAsyncTaskFactory(c.Get<IRebusLoggerFactory>())); PossiblyRegisterDefault <IAsyncTaskFactory>(c => { var rebusLoggerFactory = c.Get <IRebusLoggerFactory>(); return(new TplAsyncTaskFactory(rebusLoggerFactory)); }); 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, backoffStrategy, rebusLoggerFactory, _options, c.Get<RebusBus>); //}); PossiblyRegisterDefault <ISyncBackoffStrategy>(c => { var backoffTimes = new[] { // 10 s Enumerable.Repeat(TimeSpan.FromMilliseconds(100), 10), // on and on Enumerable.Repeat(TimeSpan.FromMilliseconds(250), 1) }; return(new DefaultSyncBackoffStrategy(backoffTimes.SelectMany(e => e))); }); PossiblyRegisterDefault <IWorkerFactory>(c => { var transport = c.Get <ITransport>(); var rebusLoggerFactory = c.Get <IRebusLoggerFactory>(); var pipeline = c.Get <IPipeline>(); var pipelineInvoker = c.Get <IPipelineInvoker>(); var options = c.Get <Options>(); var busLifetimeEvents = c.Get <BusLifetimeEvents>(); var backoffStrategy = c.Get <ISyncBackoffStrategy>(); return(new ThreadPoolWorkerFactory(transport, rebusLoggerFactory, pipeline, pipelineInvoker, options, c.Get <RebusBus>, busLifetimeEvents, backoffStrategy)); }); 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 <IErrorHandler>(c => { var settings = c.Get <SimpleRetryStrategySettings>(); var transport = c.Get <ITransport>(); var rebusLoggerFactory = c.Get <IRebusLoggerFactory>(); return(new PoisonQueueErrorHandler(settings, transport, rebusLoggerFactory)); }); PossiblyRegisterDefault <IRetryStrategy>(c => { var simpleRetryStrategySettings = c.Get <SimpleRetryStrategySettings>(); var errorTracker = c.Get <IErrorTracker>(); var errorHandler = c.Get <IErrorHandler>(); return(new SimpleRetryStrategy(simpleRetryStrategySettings, errorTracker, errorHandler)); }); 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 ValidateOutgoingMessageStep()) .OnSend(new SendOutgoingMessageStep(transport, rebusLoggerFactory))); }); RegisterDecorator <IPipeline>(c => new PipelineCache(c.Get <IPipeline>())); PossiblyRegisterDefault(c => new BusLifetimeEvents()); PossiblyRegisterDefault <IDataBus>(c => new DisabledDataBus()); // configuration hack - keep these two bad boys around to have them available at the last moment before returning the built bus instance... Action startAction = null; PossiblyRegisterDefault(c => new RebusBus( c.Get <IWorkerFactory>(), c.Get <IRouter>(), c.Get <ITransport>(), c.Get <IPipeline>(), c.Get <IPipelineInvoker>(), c.Get <ISubscriptionStorage>(), _options, c.Get <IRebusLoggerFactory>(), c.Get <BusLifetimeEvents>(), c.Get <IDataBus>())); PossiblyRegisterDefault <IBus>(c => { var bus = c.Get <RebusBus>(); bus.Disposed += () => { var disposableInstances = c.TrackedInstances.OfType <IDisposable>().Reverse(); foreach (var disposableInstance in disposableInstances) { disposableInstance.Dispose(); } }; var initializableInstances = c.TrackedInstances.OfType <IInitializable>(); foreach (var initializableInstance in initializableInstances) { initializableInstance.Initialize(); } // and then we set the startAction 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 busResolutionResult = _injectionist.Get <IBus>(); var busInstance = busResolutionResult.Instance; // if there is a container adapter among the tracked instances, hand it the bus instance var containerAdapter = busResolutionResult.TrackedInstances .OfType <IContainerAdapter>() .FirstOrDefault(); containerAdapter?.SetBus(busInstance); // and NOW we are ready to start the bus if there is a startAction startAction?.Invoke(); _hasBeenStarted = true; return(busInstance); }
/// <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); }
ResolutionResult <INanosInstance> ResolveInstance() { _logger.Verbose("Building instance"); return(_injectionist.Get <INanosInstance>()); }