/// <summary>
        /// Allows the transport to set default configuration settings or other values
        /// </summary>
        /// <param name="container">The container.</param>
        /// <param name="registrationType">Type of the registration.</param>
        /// <param name="connectionType">Type of the connection.</param>
        public override void SetDefaultsIfNeeded(IContainer container, RegistrationTypes registrationType,
                                                 ConnectionTypes connectionType)
        {
            var init = new RelationalDatabaseMessageQueueInit <long, Guid>();

            init.SetDefaultsIfNeeded(container, "SQLiteMessageQueueTransportOptions",
                                     "SQLiteMessageQueueTransportOptions");

            SetupPolicy(container);

            //create in memory hold
            var getFileName = container.GetInstance <IGetFileNameFromConnectionString>();
            var connection  = container.GetInstance <IConnectionInformation>();
            var fileName    = getFileName.GetFileName(connection.ConnectionString);

            if (!fileName.IsInMemory)
            {
                return;
            }
            var scope  = container.GetInstance <ICreationScope>();
            var holder = new SqLiteHoldConnection(getFileName, container.GetInstance <IDbFactory>());

            holder.AddConnectionIfNeeded(connection);
            scope.AddScopedObject(holder);
        }
Ejemplo n.º 2
0
        /// <inheritdoc />
        public override void SetDefaultsIfNeeded(IContainer container, RegistrationTypes registrationType, ConnectionTypes connectionType)
        {
            var init = new RelationalDatabaseMessageQueueInit <long, Guid>();

            init.SetDefaultsIfNeeded(container, "PostgreSQLMessageQueueTransportOptions", "PostgreSQLMessageQueueTransportOptions");
            SetupPolicy(container);
        }
        /// <summary>
        /// Registers the implementations.
        /// </summary>
        /// <param name="container">The container.</param>
        /// <param name="registrationType">Type of the registration.</param>
        /// <param name="queueConnection">Queue and connection information.</param>
        /// <param name="assemblies">The assemblies.</param>
        public virtual void RegisterImplementations(IContainer container, RegistrationTypes registrationType,
                                                    QueueConnection queueConnection, params Assembly[] assemblies)
        {
            Guard.NotNull(() => container, container);
            base.RegisterImplementations(container, registrationType, queueConnection);
            var init = new RelationalDatabaseMessageQueueInit <long, Guid>();

            init.RegisterStandardImplementations(container, assemblies);

            //**all
            container.RegisterNonScopedSingleton <ICreationScope>(new CreationScope());

            container.Register <SqLiteMessageQueueSchema>(LifeStyles.Singleton);
            container.Register <IQueueCreation, SqLiteMessageQueueCreation>(LifeStyles.Singleton);
            container.Register <IJobSchedulerLastKnownEvent, SqliteJobSchedulerLastKnownEvent>(LifeStyles.Singleton);
            container.Register <ISendJobToQueue, SqliteSendToJobQueue>(LifeStyles.Singleton);
            container.Register <IDbConnectionFactory, DbConnectionFactory>(LifeStyles.Singleton);
            container.Register <SqliteJobSchema>(LifeStyles.Singleton);
            container.Register <IOptionsSerialization, OptionsSerialization>(LifeStyles.Singleton);
            container.Register <CommandStringCache, IDbCommandStringCache>(LifeStyles.Singleton);
            container.Register <ITransportOptionsFactory, TransportOptionsFactory>(LifeStyles.Singleton);
            container.Register <ITransactionFactory, TransactionFactory>(LifeStyles.Singleton);
            container.Register <IJobSchema, SqliteJobSchema>(LifeStyles.Singleton);
            container.Register <IReadColumn, ReadColumn>(LifeStyles.Singleton);
            container.Register <IBuildMoveToErrorQueueSql, BuildMoveToErrorQueueSql>(LifeStyles.Singleton);
            container.Register <IGetPreviousMessageErrors, GetPreviousMessageErrors <long> >(LifeStyles.Singleton);

            container.Register <IGetFirstMessageDeliveryTime, GetFirstMessageDeliveryTime>(LifeStyles.Singleton);
            container
            .Register
            <ISqLiteMessageQueueTransportOptionsFactory, SqLiteMessageQueueTransportOptionsFactory>(
                LifeStyles.Singleton);

            container.Register <IDbCommandStringCache>(LifeStyles.Singleton);

            container.Register <IConnectionInformation>(
                () => new SqliteConnectionInformation(queueConnection, container.GetInstance <IDbDataSource>()),
                LifeStyles.Singleton);

            container.Register <BuildDequeueCommand>(LifeStyles.Singleton);
            container.Register <MessageDeQueue>(LifeStyles.Singleton);

            container.Register <SqLiteMessageQueueTransportOptions>(LifeStyles.Singleton);

            container
            .Register <IConnectionHeader <IDbConnection, IDbTransaction, IDbCommand>,
                       ConnectionHeader <IDbConnection, IDbTransaction, IDbCommand> >(LifeStyles.Singleton);
            container.Register <ISQLiteTransactionWrapper, SqLiteTransactionWrapper>(LifeStyles.Transient);
            //**all

            //**receive
            container.Register <IReceiveMessages, SqLiteMessageQueueReceive>(LifeStyles.Transient);
            container.Register <ITransportRollbackMessage, RollbackMessage>(LifeStyles.Singleton);
            container.Register <ReceiveMessage>(LifeStyles.Transient);
            //**receive

            //reset heart beat
            container
            .Register <IPrepareCommandHandler <ResetHeartBeatCommand <long> >,
                       ResetHeartBeatCommandPrepareHandler>(LifeStyles.Singleton);

            container
            .Register <IPrepareCommandHandler <MoveRecordToErrorQueueCommand <long> >,
                       MoveRecordToErrorQueueCommandPrepareHandler>(LifeStyles.Singleton);

            //explicit registration of our job exists query
            container
            .Register <IQueryHandler <DoesJobExistQuery <IDbConnection, IDbTransaction>,
                                      QueueStatuses>,
                       DoesJobExistQueryHandler <IDbConnection, IDbTransaction> >(LifeStyles.Singleton);

            //because we have an explicit registration for job exists, we need to explicitly register the prepare statement
            container
            .Register <IPrepareQueryHandler <DoesJobExistQuery <IDbConnection, IDbTransaction>,
                                             QueueStatuses>,
                       DoesJobExistQueryPrepareHandler <IDbConnection, IDbTransaction> >(LifeStyles.Singleton);

            container
            .Register <ICommandHandler <MoveRecordToErrorQueueCommand <long> >,
                       MoveRecordToErrorQueueCommandHandler <IDbConnection, IDbTransaction, IDbCommand> >(LifeStyles
                                                                                                          .Singleton);

            //expired messages
            container
            .Register <IPrepareQueryHandler <FindExpiredMessagesToDeleteQuery <long>, IEnumerable <long> >,
                       FindExpiredRecordsToDeleteQueryPrepareHandler>(LifeStyles.Singleton);

            //error messages
            container
            .Register <IPrepareQueryHandler <FindErrorMessagesToDeleteQuery <long>, IEnumerable <long> >,
                       FindErrorRecordsToDeleteQueryPrepareHandler>(LifeStyles.Singleton);

            //heartbeat
            container
            .Register <IPrepareQueryHandler <FindMessagesToResetByHeartBeatQuery <long>, IEnumerable <MessageToReset <long> > >,
                       FindRecordsToResetByHeartBeatQueryPrepareHandler>(LifeStyles.Singleton);

            //explicit registration of options
            container
            .Register <IQueryHandler <GetQueueOptionsQuery <SqLiteMessageQueueTransportOptions>,
                                      SqLiteMessageQueueTransportOptions>,
                       GetQueueOptionsQueryHandler <SqLiteMessageQueueTransportOptions> >(LifeStyles.Singleton);

            container
            .Register <IPrepareQueryHandler <GetQueueOptionsQuery <SqLiteMessageQueueTransportOptions>,
                                             SqLiteMessageQueueTransportOptions>,
                       GetQueueOptionsQueryPrepareHandler <SqLiteMessageQueueTransportOptions> >(LifeStyles.Singleton);

            container.RegisterDecorator(typeof(ISQLiteTransactionWrapper),
                                        typeof(BeginTransactionRetryDecorator), LifeStyles.Transient);

            //register our decorator for deleting messages
            container.RegisterDecorator(
                typeof(ICommandHandlerWithOutput <DeleteMessageCommand <long>, long>),
                typeof(DeleteMessageCommandDecorator), LifeStyles.Singleton);

            //register our decorator for setting the status
            container.RegisterDecorator(
                typeof(ICommandHandler <DeleteStatusTableStatusCommand <long> >),
                typeof(SetStatusTableStatusCommandDecorator), LifeStyles.Singleton);

            //register our decorator for resetting the heart beat
            container.RegisterDecorator(
                typeof(ICommandHandlerWithOutput <ResetHeartBeatCommand <long>, long>),
                typeof(ResetHeartBeatCommandDecorator), LifeStyles.Singleton);

            container.RegisterDecorator(
                typeof(ICommandHandler <MoveRecordToErrorQueueCommand <long> >),
                typeof(MoveRecordToErrorQueueCommandDecorator), LifeStyles.Singleton);

            container.RegisterDecorator(
                typeof(IQueryHandler <GetErrorRecordExistsQuery <long>, bool>),
                typeof(GetErrorRecordExistsQueryDecorator), LifeStyles.Singleton);

            container.RegisterDecorator(
                typeof(IQueryHandler <FindExpiredMessagesToDeleteQuery <long>, IEnumerable <long> >),
                typeof(FindExpiredRecordsToDeleteDecorator), LifeStyles.Singleton);

            container.RegisterDecorator(
                typeof(IQueryHandler <FindMessagesToResetByHeartBeatQuery <long>, IEnumerable <MessageToReset <long> > >),
                typeof(FindRecordsToResetByHeartBeatDecorator), LifeStyles.Singleton);

            container.RegisterDecorator(
                typeof(IQueryHandler <GetColumnNamesFromTableQuery, List <string> >),
                typeof(GetColumnNamesFromTableDecorator), LifeStyles.Singleton);

            container.RegisterDecorator(
                typeof(IQueryHandler <GetTableExistsQuery, bool>),
                typeof(GetTableExistsDecorator), LifeStyles.Singleton);

            container.RegisterDecorator(
                typeof(IQueryHandler <DoesJobExistQuery <IDbConnection, IDbTransaction>, QueueStatuses>),
                typeof(DoesJobExistDecorator), LifeStyles.Singleton);

            container.RegisterDecorator(
                typeof(ICommandHandlerWithOutput <DeleteQueueTablesCommand, QueueRemoveResult>),
                typeof(DeleteQueueTablesDecorator), LifeStyles.Singleton);

            container.RegisterDecorator(
                typeof(ICommandHandler <SetErrorCountCommand <long> >),
                typeof(SetErrorCountCommandDecorator), LifeStyles.Singleton);

            //trace fallback command
            container.RegisterDecorator(
                typeof(ICommandHandler <RollbackMessageCommand <long> >),
                typeof(DotNetWorkQueue.Transport.SQLite.Trace.Decorator.RollbackMessageCommandHandlerDecorator), LifeStyles.Singleton);

            //trace sending a message so that we can add specific tags
            container.RegisterDecorator(
                typeof(ICommandHandlerWithOutput <SendMessageCommand, long>),
                typeof(DotNetWorkQueue.Transport.SQLite.Trace.Decorator.SendMessageCommandHandlerDecorator), LifeStyles.Singleton);

            container.RegisterDecorator(
                typeof(ICommandHandlerWithOutputAsync <SendMessageCommand, long>),
                typeof(DotNetWorkQueue.Transport.SQLite.Trace.Decorator.SendMessageCommandHandlerAsyncDecorator), LifeStyles.Singleton);
        }
        /// <summary>
        /// Registers the implementations.
        /// </summary>
        /// <param name="container">The container.</param>
        /// <param name="registrationType">Type of the registration.</param>
        /// <param name="connection">The connection.</param>
        /// <param name="queue">The queue.</param>
        public override void RegisterImplementations(IContainer container, RegistrationTypes registrationType, string connection, string queue)
        {
            Guard.NotNull(() => container, container);

            var init = new RelationalDatabaseMessageQueueInit();

            init.RegisterStandardImplementations(container, Assembly.GetAssembly(GetType()));

            //**all
            container.Register <IDbConnectionFactory, DbConnectionFactory>(LifeStyles.Singleton);
            container.Register <SqlServerMessageQueueSchema>(LifeStyles.Singleton);
            container.Register <IQueueCreation, SqlServerMessageQueueCreation>(LifeStyles.Singleton);
            container.Register <IJobSchedulerLastKnownEvent, SqlServerJobSchedulerLastKnownEvent>(LifeStyles.Singleton);
            container.Register <SqlServerJobSchema>(LifeStyles.Singleton);
            container.Register <ISendJobToQueue, SqlServerSendJobToQueue>(LifeStyles.Singleton);
            container.Register <CommandStringCache, SqlServerCommandStringCache>(LifeStyles.Singleton);
            container.Register <IOptionsSerialization, OptionsSerialization>(LifeStyles.Singleton);
            container.Register <IJobSchema, SqlServerJobSchema>(LifeStyles.Singleton);
            container.Register <IReadColumn, ReadColumn>(LifeStyles.Singleton);
            container.Register <IBuildMoveToErrorQueueSql, BuildMoveToErrorQueueSql>(LifeStyles.Singleton);
            container.Register <ITransportOptionsFactory, TransportOptionsFactory>(LifeStyles.Singleton);

            container.Register <IGetTime, SqlServerTime>(LifeStyles.Singleton);
            container.Register <IGetFirstMessageDeliveryTime, GetFirstMessageDeliveryTime>(LifeStyles.Singleton);
            container
            .Register
            <ISqlServerMessageQueueTransportOptionsFactory, SqlServerMessageQueueTransportOptionsFactory>(
                LifeStyles.Singleton);

            container.Register <ICreationScope, CreationScopeNoOp>(LifeStyles.Singleton);
            container.Register <SqlServerCommandStringCache>(LifeStyles.Singleton);

            container.Register <IConnectionInformation>(() => new SqlConnectionInformation(queue, connection), LifeStyles.Singleton);

            container.Register <SqlServerMessageQueueTransportOptions>(LifeStyles.Singleton);
            container.Register <IConnectionHeader <SqlConnection, SqlTransaction, SqlCommand>, ConnectionHeader <SqlConnection, SqlTransaction, SqlCommand> >(LifeStyles.Singleton);
            //**all

            //**receive
            container.Register <IReceiveMessages, SqlServerMessageQueueReceive>(LifeStyles.Transient);
            container.Register <IConnectionHolderFactory <SqlConnection, SqlTransaction, SqlCommand>, ConnectionHolderFactory>(LifeStyles.Singleton);
            container.Register <CommitMessage>(LifeStyles.Transient);
            container.Register <RollbackMessage>(LifeStyles.Transient);
            container.Register <HandleMessage>(LifeStyles.Transient);
            container.Register <ReceiveMessage>(LifeStyles.Transient);
            container.Register <CreateDequeueStatement>(LifeStyles.Singleton);
            container.Register <BuildDequeueCommand>(LifeStyles.Singleton);
            container.Register <ReadMessage>(LifeStyles.Singleton);
            //**receive

            //explicit registration of our job exists query
            container
            .Register <IQueryHandler <DoesJobExistQuery <SqlConnection, SqlTransaction>,
                                      QueueStatuses>,
                       DoesJobExistQueryHandler <SqlConnection, SqlTransaction> >(LifeStyles.Singleton);

            //because we have an explicit registration for job exists, we need to explicitly register the prepare statement
            container
            .Register <IPrepareQueryHandler <DoesJobExistQuery <SqlConnection, SqlTransaction>,
                                             QueueStatuses>,
                       DoesJobExistQueryPrepareHandler <SqlConnection, SqlTransaction> >(LifeStyles.Singleton);

            container
            .Register <ICommandHandlerWithOutput <SendHeartBeatCommand, DateTime?>,
                       SendHeartBeatCommandHandler>(LifeStyles.Singleton);

            container
            .Register <ICommandHandler <MoveRecordToErrorQueueCommand>,
                       MoveRecordToErrorQueueCommandHandler <SqlConnection, SqlTransaction, SqlCommand> >(LifeStyles.Singleton);

            //explicit registration of options
            container
            .Register <IQueryHandler <GetQueueOptionsQuery <SqlServerMessageQueueTransportOptions>, SqlServerMessageQueueTransportOptions>,
                       GetQueueOptionsQueryHandler <SqlServerMessageQueueTransportOptions> >(LifeStyles.Singleton);

            container
            .Register <ICommandHandlerWithOutput <DeleteTransactionalMessageCommand, long>,
                       DeleteTransactionalMessageCommandHandler <SqlConnection, SqlTransaction, SqlCommand> >(LifeStyles.Singleton);

            container
            .Register <IPrepareQueryHandler <GetQueueOptionsQuery <SqlServerMessageQueueTransportOptions>,
                                             SqlServerMessageQueueTransportOptions>,
                       GetQueueOptionsQueryPrepareHandler <SqlServerMessageQueueTransportOptions> >(LifeStyles.Singleton);

            container.RegisterDecorator(typeof(ICommandHandlerWithOutput <,>),
                                        typeof(RetryCommandHandlerOutputDecorator <,>), LifeStyles.Singleton);

            container.RegisterDecorator(typeof(ICommandHandler <>),
                                        typeof(RetryCommandHandlerDecorator <>), LifeStyles.Singleton);

            container.RegisterDecorator(typeof(ICommandHandlerWithOutputAsync <,>),
                                        typeof(RetryCommandHandlerOutputDecoratorAsync <,>), LifeStyles.Singleton);

            container.RegisterDecorator(typeof(IQueryHandler <,>),
                                        typeof(RetryQueryHandlerDecorator <,>), LifeStyles.Singleton);

            //register our decorator that handles table creation errors
            container.RegisterDecorator(
                typeof(ICommandHandlerWithOutput <CreateJobTablesCommand <ITable>, QueueCreationResult>),
                typeof(CreateJobTablesCommandDecorator), LifeStyles.Singleton);

            //register our decorator that handles table creation errors
            container.RegisterDecorator(
                typeof(ICommandHandlerWithOutput <CreateQueueTablesAndSaveConfigurationCommand <ITable>, QueueCreationResult>),
                typeof(CreateQueueTablesAndSaveConfigurationDecorator), LifeStyles.Singleton);
        }
Ejemplo n.º 5
0
        /// <inheritdoc />
        public override void RegisterImplementations(IContainer container, RegistrationTypes registrationType,
                                                     QueueConnection queueConnection)
        {
            Guard.NotNull(() => container, container);
            base.RegisterImplementations(container, registrationType, queueConnection);

            var init = new RelationalDatabaseMessageQueueInit <long, Guid>();

            init.RegisterStandardImplementations(container, Assembly.GetAssembly(GetType()));

            //**all
            container.Register <IDbConnectionFactory, DbConnectionFactory>(LifeStyles.Singleton);
            container.Register <PostgreSqlMessageQueueSchema>(LifeStyles.Singleton);
            container.Register <IQueueCreation, PostgreSqlMessageQueueCreation>(LifeStyles.Singleton);
            container.Register <IJobSchedulerLastKnownEvent, PostgreSqlJobSchedulerLastKnownEvent>(LifeStyles.Singleton);
            container.Register <IOptionsSerialization, OptionsSerialization>(LifeStyles.Singleton);
            container.Register <PostgreSqlJobSchema>(LifeStyles.Singleton);
            container.Register <ISendJobToQueue, PostgreSqlSendJobToQueue>(LifeStyles.Singleton);
            container.Register <CommandStringCache, PostgreSqlCommandStringCache>(LifeStyles.Singleton);
            container.Register <IJobSchema, PostgreSqlJobSchema>(LifeStyles.Singleton);
            container.Register <IReadColumn, ReadColumn>(LifeStyles.Singleton);
            container.Register <ITransportOptionsFactory, TransportOptionsFactory>(LifeStyles.Singleton);
            container.Register <IGetPreviousMessageErrors, GetPreviousMessageErrors <long> >(LifeStyles.Singleton);

            container.Register <IRemoveMessage, RemoveMessage>(LifeStyles.Singleton);

            container.Register <IGetTime, PostgreSqlTime>(LifeStyles.Singleton);
            container.Register <IGetFirstMessageDeliveryTime, GetFirstMessageDeliveryTime>(LifeStyles.Singleton);
            container
            .Register
            <IPostgreSqlMessageQueueTransportOptionsFactory, PostgreSqlMessageQueueTransportOptionsFactory>(
                LifeStyles.Singleton);

            container.Register <PostgreSqlCommandStringCache>(LifeStyles.Singleton);
            container.Register <IConnectionInformation>(() => new SqlConnectionInformation(queueConnection),
                                                        LifeStyles.Singleton);

            container.Register <PostgreSqlMessageQueueTransportOptions>(LifeStyles.Singleton);
            container.Register <IConnectionHeader <NpgsqlConnection, NpgsqlTransaction, NpgsqlCommand>, ConnectionHeader <NpgsqlConnection, NpgsqlTransaction, NpgsqlCommand> >(LifeStyles.Singleton);
            //**all

            //**receive
            container.Register <IReceiveMessages, PostgreSqlMessageQueueReceive>(LifeStyles.Transient);
            container.Register <IConnectionHolderFactory <NpgsqlConnection, NpgsqlTransaction, NpgsqlCommand>, ConnectionHolderFactory>(LifeStyles.Singleton);
            container.Register <ITransportRollbackMessage, RollbackMessage>(LifeStyles.Singleton);
            container.Register <ReceiveMessage>(LifeStyles.Transient);
            container.Register <IBuildMoveToErrorQueueSql, BuildMoveToErrorQueueSql>(LifeStyles.Singleton);
            //**receive

            //reset heart beat
            container
            .Register <IPrepareCommandHandler <ResetHeartBeatCommand <long> >,
                       ResetHeartBeatCommandPrepareHandler>(LifeStyles.Singleton);

            //delete table - need lower case
            container
            .Register <IPrepareCommandHandler <DeleteTableCommand>,
                       DeleteTableCommandPrepareHandler>(LifeStyles.Singleton);

            //explicit registration of our job exists query
            container
            .Register <IQueryHandler <DoesJobExistQuery <NpgsqlConnection, NpgsqlTransaction>,
                                      QueueStatuses>,
                       DoesJobExistQueryHandler <NpgsqlConnection, NpgsqlTransaction> >(LifeStyles.Singleton);

            //because we have an explicit registration for job exists, we need to explicitly register the prepare statement
            container
            .Register <IPrepareQueryHandler <DoesJobExistQuery <NpgsqlConnection, NpgsqlTransaction>,
                                             QueueStatuses>,
                       DoesJobExistQueryPrepareHandler <NpgsqlConnection, NpgsqlTransaction> >(LifeStyles.Singleton);

            //expired messages
            container
            .Register <IPrepareQueryHandler <FindExpiredMessagesToDeleteQuery <long>, IEnumerable <long> >,
                       FindExpiredRecordsToDeleteQueryPrepareHandler>(LifeStyles.Singleton);

            //error messages
            container
            .Register <IPrepareQueryHandler <FindErrorMessagesToDeleteQuery <long>, IEnumerable <long> >,
                       FindErrorRecordsToDeleteQueryPrepareHandler>(LifeStyles.Singleton);

            //heartbeat
            container
            .Register <IPrepareQueryHandler <FindMessagesToResetByHeartBeatQuery <long>, IEnumerable <MessageToReset <long> > >,
                       FindRecordsToResetByHeartBeatQueryPrepareHandler>(LifeStyles.Singleton);

            container
            .Register <ICommandHandlerWithOutput <DeleteTransactionalMessageCommand, long>,
                       DeleteTransactionalMessageCommandHandler <NpgsqlConnection, NpgsqlTransaction, NpgsqlCommand> >(LifeStyles.Singleton);

            container
            .Register <ICommandHandler <MoveRecordToErrorQueueCommand <long> >,
                       MoveRecordToErrorQueueCommandHandler <NpgsqlConnection, NpgsqlTransaction, NpgsqlCommand> >(LifeStyles.Singleton);

            //explicit registration of options
            container
            .Register <IQueryHandler <GetQueueOptionsQuery <PostgreSqlMessageQueueTransportOptions>,
                                      PostgreSqlMessageQueueTransportOptions>,
                       GetQueueOptionsQueryHandler <PostgreSqlMessageQueueTransportOptions> >(LifeStyles.Singleton);

            container
            .Register <IPrepareQueryHandler <GetQueueOptionsQuery <PostgreSqlMessageQueueTransportOptions>,
                                             PostgreSqlMessageQueueTransportOptions>,
                       GetQueueOptionsQueryPrepareHandler <PostgreSqlMessageQueueTransportOptions> >(LifeStyles.Singleton);

            container.RegisterDecorator(typeof(IPrepareQueryHandler <GetColumnNamesFromTableQuery, List <string> >),
                                        typeof(GetColumnNamesFromTableQueryPrepareDecorator), LifeStyles.Singleton);

            container.RegisterDecorator(typeof(IPrepareQueryHandler <GetTableExistsQuery, bool>),
                                        typeof(GetTableExistsQueryPrepareDecorator), LifeStyles.Singleton);

            container.RegisterDecorator(typeof(IPrepareQueryHandler <GetTableExistsTransactionQuery, bool>),
                                        typeof(GetTableExistsTransactionQueryPrepareDecorator), LifeStyles.Singleton);

            container.RegisterDecorator(typeof(ICommandHandlerWithOutput <,>),
                                        typeof(RetryCommandHandlerOutputDecorator <,>), LifeStyles.Singleton);

            container.RegisterDecorator(typeof(ICommandHandler <>),
                                        typeof(RetryCommandHandlerDecorator <>), LifeStyles.Singleton);

            container.RegisterDecorator(typeof(ICommandHandlerWithOutputAsync <,>),
                                        typeof(RetryCommandHandlerOutputDecoratorAsync <,>), LifeStyles.Singleton);

            container.RegisterDecorator(typeof(IQueryHandler <,>),
                                        typeof(RetryQueryHandlerDecorator <,>), LifeStyles.Singleton);

            //register our decorator that handles table creation errors
            container.RegisterDecorator(
                typeof(ICommandHandlerWithOutput <CreateJobTablesCommand <ITable>, QueueCreationResult>),
                typeof(CreateJobTablesCommandDecorator), LifeStyles.Singleton);

            //register our decorator that handles table creation errors
            container.RegisterDecorator(
                typeof(ICommandHandlerWithOutput <CreateQueueTablesAndSaveConfigurationCommand <ITable>,
                                                  QueueCreationResult>),
                typeof(CreateQueueTablesAndSaveConfigurationDecorator), LifeStyles.Singleton);

            //trace fallback command
            container.RegisterDecorator(
                typeof(ICommandHandler <RollbackMessageCommand <long> >),
                typeof(DotNetWorkQueue.Transport.PostgreSQL.Trace.Decorator.RollbackMessageCommandHandlerDecorator), LifeStyles.Singleton);

            //trace sending a message so that we can add specific tags
            container.RegisterDecorator(
                typeof(ICommandHandlerWithOutput <SendMessageCommand, long>),
                typeof(DotNetWorkQueue.Transport.PostgreSQL.Trace.Decorator.SendMessageCommandHandlerDecorator), LifeStyles.Singleton);

            container.RegisterDecorator(
                typeof(ICommandHandlerWithOutputAsync <SendMessageCommand, long>),
                typeof(DotNetWorkQueue.Transport.PostgreSQL.Trace.Decorator.SendMessageCommandHandlerAsyncDecorator), LifeStyles.Singleton);
        }
        /// <summary>
        /// Registers the implementations.
        /// </summary>
        /// <param name="container">The container.</param>
        /// <param name="registrationType">Type of the registration.</param>
        /// <param name="queueConnection">Queue and connection information.</param>
        public override void RegisterImplementations(IContainer container, RegistrationTypes registrationType, QueueConnection queueConnection)
        {
            Guard.NotNull(() => container, container);
            base.RegisterImplementations(container, registrationType, queueConnection);

            var init = new RelationalDatabaseMessageQueueInit <long, Guid>();

            init.RegisterStandardImplementations(container, Assembly.GetAssembly(GetType()));

            //override so that we can use schema as needed
            container.Register <ITableNameHelper, SqlServerTableNameHelper>(LifeStyles.Singleton);

            //**all
            container.Register <IDbConnectionFactory, DbConnectionFactory>(LifeStyles.Singleton);
            container.Register <SqlServerMessageQueueSchema>(LifeStyles.Singleton);
            container.Register <IQueueCreation, SqlServerMessageQueueCreation>(LifeStyles.Singleton);
            container.Register <IJobSchedulerLastKnownEvent, SqlServerJobSchedulerLastKnownEvent>(LifeStyles.Singleton);
            container.Register <SqlServerJobSchema>(LifeStyles.Singleton);
            container.Register <ISendJobToQueue, SqlServerSendJobToQueue>(LifeStyles.Singleton);
            container.Register <CommandStringCache, SqlServerCommandStringCache>(LifeStyles.Singleton);
            container.Register <IOptionsSerialization, OptionsSerialization>(LifeStyles.Singleton);
            container.Register <IJobSchema, SqlServerJobSchema>(LifeStyles.Singleton);
            container.Register <IReadColumn, ReadColumn>(LifeStyles.Singleton);
            container.Register <IBuildMoveToErrorQueueSql, BuildMoveToErrorQueueSql>(LifeStyles.Singleton);
            container.Register <ITransportOptionsFactory, TransportOptionsFactory>(LifeStyles.Singleton);
            container.Register <IRemoveMessage, RemoveMessage>(LifeStyles.Singleton);
            container.Register <IGetPreviousMessageErrors, GetPreviousMessageErrors <long> >(LifeStyles.Singleton);
            container.Register <ISqlSchema, SqlSchema>(LifeStyles.Singleton);

            container.Register <IGetTime, SqlServerTime>(LifeStyles.Singleton);
            container.Register <IGetFirstMessageDeliveryTime, GetFirstMessageDeliveryTime>(LifeStyles.Singleton);
            container
            .Register
            <ISqlServerMessageQueueTransportOptionsFactory, SqlServerMessageQueueTransportOptionsFactory>(
                LifeStyles.Singleton);

            container.Register <ICreationScope, CreationScopeNoOp>(LifeStyles.Singleton);
            container.Register <SqlServerCommandStringCache>(LifeStyles.Singleton);

            container.Register <IConnectionInformation>(() => new SqlConnectionInformation(queueConnection), LifeStyles.Singleton);

            container.Register <SqlServerMessageQueueTransportOptions>(LifeStyles.Singleton);
            container.Register <IConnectionHeader <SqlConnection, SqlTransaction, SqlCommand>, ConnectionHeader <SqlConnection, SqlTransaction, SqlCommand> >(LifeStyles.Singleton);
            //**all

            //**receive
            container.Register <IReceiveMessages, SqlServerMessageQueueReceive>(LifeStyles.Transient);
            container.Register <IConnectionHolderFactory <SqlConnection, SqlTransaction, SqlCommand>, ConnectionHolderFactory>(LifeStyles.Singleton);
            container.Register <ITransportRollbackMessage, RollbackMessage>(LifeStyles.Singleton);
            container.Register <ReceiveMessage>(LifeStyles.Transient);
            container.Register <CreateDequeueStatement>(LifeStyles.Singleton);
            container.Register <BuildDequeueCommand>(LifeStyles.Singleton);
            container.Register <ReadMessage>(LifeStyles.Singleton);
            //**receive

            //explicit registration of our job exists query
            container
            .Register <IQueryHandler <DoesJobExistQuery <SqlConnection, SqlTransaction>,
                                      QueueStatuses>,
                       DoesJobExistQueryHandler <SqlConnection, SqlTransaction> >(LifeStyles.Singleton);

            //because we have an explicit registration for job exists, we need to explicitly register the prepare statement
            container
            .Register <IPrepareQueryHandler <DoesJobExistQuery <SqlConnection, SqlTransaction>,
                                             QueueStatuses>,
                       DoesJobExistQueryPrepareHandler <SqlConnection, SqlTransaction> >(LifeStyles.Singleton);

            container
            .Register <ICommandHandlerWithOutput <SendHeartBeatCommand <long>, DateTime?>,
                       SendHeartBeatCommandHandler>(LifeStyles.Singleton);

            container
            .Register <ICommandHandler <MoveRecordToErrorQueueCommand <long> >,
                       MoveRecordToErrorQueueCommandHandler <SqlConnection, SqlTransaction, SqlCommand> >(LifeStyles.Singleton);

            //explicit registration of options
            container
            .Register <IQueryHandler <GetQueueOptionsQuery <SqlServerMessageQueueTransportOptions>, SqlServerMessageQueueTransportOptions>,
                       GetQueueOptionsQueryHandler <SqlServerMessageQueueTransportOptions> >(LifeStyles.Singleton);

            container
            .Register <ICommandHandlerWithOutput <DeleteTransactionalMessageCommand, long>,
                       DeleteTransactionalMessageCommandHandler <SqlConnection, SqlTransaction, SqlCommand> >(LifeStyles.Singleton);

            container
            .Register <IPrepareQueryHandler <GetQueueOptionsQuery <SqlServerMessageQueueTransportOptions>,
                                             SqlServerMessageQueueTransportOptions>,
                       GetQueueOptionsQueryPrepareHandler <SqlServerMessageQueueTransportOptions> >(LifeStyles.Singleton);

            container.RegisterDecorator(typeof(ICommandHandlerWithOutput <,>),
                                        typeof(RetryCommandHandlerOutputDecorator <,>), LifeStyles.Singleton);

            container.RegisterDecorator(typeof(ICommandHandler <>),
                                        typeof(RetryCommandHandlerDecorator <>), LifeStyles.Singleton);

            container.RegisterDecorator(typeof(ICommandHandlerWithOutputAsync <,>),
                                        typeof(RetryCommandHandlerOutputDecoratorAsync <,>), LifeStyles.Singleton);

            container.RegisterDecorator(typeof(IQueryHandler <,>),
                                        typeof(RetryQueryHandlerDecorator <,>), LifeStyles.Singleton);

            //register our decorator that handles table creation errors
            container.RegisterDecorator(
                typeof(ICommandHandlerWithOutput <CreateJobTablesCommand <ITable>, QueueCreationResult>),
                typeof(CreateJobTablesCommandDecorator), LifeStyles.Singleton);

            //register our decorator that handles table creation errors
            container.RegisterDecorator(
                typeof(ICommandHandlerWithOutput <CreateQueueTablesAndSaveConfigurationCommand <ITable>, QueueCreationResult>),
                typeof(CreateQueueTablesAndSaveConfigurationDecorator), LifeStyles.Singleton);

            //trace fallback command
            container.RegisterDecorator(
                typeof(ICommandHandler <RollbackMessageCommand <long> >),
                typeof(DotNetWorkQueue.Transport.SqlServer.Trace.Decorator.RollbackMessageCommandHandlerDecorator), LifeStyles.Singleton);

            //trace sending a message so that we can add specific tags
            container.RegisterDecorator(
                typeof(ICommandHandlerWithOutput <SendMessageCommand, long>),
                typeof(DotNetWorkQueue.Transport.SqlServer.Trace.Decorator.SendMessageCommandHandlerDecorator), LifeStyles.Singleton);

            container.RegisterDecorator(
                typeof(ICommandHandlerWithOutputAsync <SendMessageCommand, long>),
                typeof(DotNetWorkQueue.Transport.SqlServer.Trace.Decorator.SendMessageCommandHandlerAsyncDecorator), LifeStyles.Singleton);

            //query exists custom handler for SQL server
            container
            .Register <IPrepareQueryHandler <GetTableExistsQuery, bool>,
                       DotNetWorkQueue.Transport.SqlServer.Basic.QueryPrepareHandler.GetTableExistsQueryPrepareHandler>(LifeStyles.Singleton);

            //query exists custom handler for SQL server
            container
            .Register <IPrepareQueryHandler <GetTableExistsTransactionQuery, bool>,
                       DotNetWorkQueue.Transport.SqlServer.Basic.QueryPrepareHandler.GetTableExistsTransactionQueryPrepareHandler>(LifeStyles.Singleton);
        }