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);
        }
Example #4
0
        public void NoCloudDataSourceRegistered()
        {
            var container = new Injectionist();
            var builder   = new ConfigDriveBuilder(container);

            builder.NoCloud(new NoCloudConfigDriveMetaData());

            Assert.IsType <NoCloudDataSource>(container.Get <IConfigDriveDataSource>().Instance);
        }
Example #5
0
        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);
    }
Example #7
0
        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",
            }));
        }
Example #9
0
    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);
    }
Example #10
0
        /// <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;
            }
        }
Example #11
0
        /// <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);
        }
Example #12
0
        /// <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);
        }
Example #13
0
        /// <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);
        }
Example #14
0
        ResolutionResult <INanosInstance> ResolveInstance()
        {
            _logger.Verbose("Building instance");

            return(_injectionist.Get <INanosInstance>());
        }