示例#1
0
        /// <summary>
        /// Uses the Brighter In-Memory Inbox to store messages received to support once-only messaging and diagnostics
        /// Advantages: Fast and no additional infrastructure required
        /// Disadvantages: The inbox will not survive restarts, so messages will not be de-duped if received after a restart.
        ///                The inbox will not work across threads/processes so only works with a single performer/consumer.
        /// Registers singletons with the service collection:
        ///  - InMemoryInboxSync - what messages have we received
        ///  - InMemoryInboxAsync - what messages have we recived (async pipeline compatible)
        /// </summary>
        /// <param name="brighterBuilder"></param>
        /// <returns></returns>
        public static IBrighterBuilder UseInMemoryInbox(this IBrighterBuilder brighterBuilder)
        {
            brighterBuilder.Services.Add(new ServiceDescriptor(typeof(IAmAnInboxSync), _ => new InMemoryInbox(), ServiceLifetime.Singleton));
            brighterBuilder.Services.Add(new ServiceDescriptor(typeof(IAmAnInboxAsync), _ => new InMemoryInbox(), ServiceLifetime.Singleton));

            return(brighterBuilder);
        }
        public static IBrighterBuilder UsePostgreSqlOutbox(
            this IBrighterBuilder brighterBuilder, PostgreSqlOutboxConfiguration configuration, Type connectionProvider = null, ServiceLifetime serviceLifetime = ServiceLifetime.Singleton)
        {
            if (brighterBuilder is null)
            {
                throw new ArgumentNullException($"{nameof(brighterBuilder)} cannot be null.", nameof(brighterBuilder));
            }

            if (configuration is null)
            {
                throw new ArgumentNullException($"{nameof(configuration)} cannot be null.", nameof(configuration));
            }

            brighterBuilder.Services.AddSingleton <PostgreSqlOutboxConfiguration>(configuration);

            if (connectionProvider is object)
            {
                if (!typeof(IPostgreSqlConnectionProvider).IsAssignableFrom(connectionProvider))
                {
                    throw new Exception($"Unable to register provider of type {connectionProvider.GetType().Name}. Class does not implement interface {nameof(IPostgreSqlConnectionProvider)}.");
                }

                brighterBuilder.Services.Add(new ServiceDescriptor(typeof(IPostgreSqlConnectionProvider), connectionProvider, serviceLifetime));
            }

            brighterBuilder.Services.Add(new ServiceDescriptor(typeof(IAmAnOutboxSync <Message>), BuildPostgreSqlOutboxSync, serviceLifetime));

            return(brighterBuilder);
        }
示例#3
0
        /// <summary>
        /// Use this transaction provider to ensure that the Outbox and the Entity Store are correct
        /// </summary>
        /// <param name="brighterBuilder">Allows extension method</param>
        /// <param name="connectionProvider">What is the tyoe of the connection provider</param>
        /// <param name="serviceLifetime">What is the lifetime of registered interfaces</param>
        /// <returns>Allows fluent syntax</returns>
        /// This is paired with Use Outbox (above) when required
        /// Registers the following
        /// -- IAmABoxTransactionConnectionProvider: the provider of a connection for any existing transaction
        public static IBrighterBuilder UseMsSqlTransactionConnectionProvider(
            this IBrighterBuilder brighterBuilder, Type connectionProvider,
            ServiceLifetime serviceLifetime = ServiceLifetime.Scoped)
        {
            brighterBuilder.Services.Add(new ServiceDescriptor(typeof(IAmABoxTransactionConnectionProvider), connectionProvider, serviceLifetime));

            return(brighterBuilder);
        }
示例#4
0
        /// <summary>
        /// An external bus is the use of Message Oriented Middleware (MoM) to dispatch a message between a producer and a consumer. The assumption is that this
        /// is being used for inter-process communication, for example the work queue pattern for distributing work, or between microservicves
        /// Registers singletons with the service collection :-
        ///  - Producer - the Gateway wrapping access to Middleware
        ///  - UseRpc - do we want to use Rpc i.e. a command blocks waiting for a response, over middleware
        /// </summary>
        /// <param name="brighterBuilder">The Brighter builder to add this option to</param>
        /// <param name="producerRegistry">The collection of producers - clients that connect to a specific transport</param>
        /// <param name="useRequestResponseQueues">Add support for RPC over MoM by using a reply queue</param>
        /// <param name="replyQueueSubscriptions">Reply queue subscription</param>
        /// <returns>The Brighter builder to allow chaining of requests</returns>
        public static IBrighterBuilder UseExternalBus(this IBrighterBuilder brighterBuilder, IAmAProducerRegistry producerRegistry, bool useRequestResponseQueues = false, IEnumerable <Subscription> replyQueueSubscriptions = null)
        {
            brighterBuilder.Services.AddSingleton <IAmAProducerRegistry>(producerRegistry);

            brighterBuilder.Services.AddSingleton <IUseRpc>(new UseRpc(useRequestResponseQueues, replyQueueSubscriptions));

            return(brighterBuilder);
        }
示例#5
0
        public static IBrighterBuilder UseEventStoreOutbox(
            this IBrighterBuilder brighterBuilder, IEventStoreConnection connection, ServiceLifetime serviceLifetime = ServiceLifetime.Singleton)
        {
            brighterBuilder.Services.AddSingleton <IEventStoreConnection>(connection);

            brighterBuilder.Services.Add(new ServiceDescriptor(typeof(IAmAnOutboxSync <Message>), BuildEventStoreOutbox, serviceLifetime));
            brighterBuilder.Services.Add(new ServiceDescriptor(typeof(IAmAnOutboxAsync <Message>), BuildEventStoreOutbox, serviceLifetime));

            return(brighterBuilder);
        }
示例#6
0
        /// <summary>
        /// Use MsSql for the Outbox
        /// </summary>
        /// <param name="brighterBuilder">Allows extension method syntax</param>
        /// <param name="configuration">The connection for the Db and name of the Outbox table</param>
        /// <param name="connectionProvider">What is the type for the class that lets us obtain connections for the Sqlite database</param>
        /// <param name="serviceLifetime">What is the lifetime of the services that we add</param>
        /// <returns>Allows fluent syntax</returns>
        /// -- Registers the following
        /// -- MsSqlConfigutation: connection string and outbox name
        /// -- IMsSqlConnectionProvider: lets us get a connection for the outbox that matches the entity store
        /// -- IAmAnOutbox<Message>: an outbox to store messages we want to send
        /// -- IAmAnOutboxAsync<Message>: an outbox to store messages we want to send
        /// -- IAmAnOutboxViewer<Message>: Lets us read the entries in the outbox
        /// -- IAmAnOutboxViewerAsync<Message>: Lets us read the entries in the outbox
        public static IBrighterBuilder UseMsSqlOutbox(
            this IBrighterBuilder brighterBuilder, MsSqlConfiguration configuration, Type connectionProvider, ServiceLifetime serviceLifetime = ServiceLifetime.Singleton)
        {
            brighterBuilder.Services.AddSingleton <MsSqlConfiguration>(configuration);
            brighterBuilder.Services.Add(new ServiceDescriptor(typeof(IMsSqlConnectionProvider), connectionProvider, serviceLifetime));

            brighterBuilder.Services.Add(new ServiceDescriptor(typeof(IAmAnOutboxSync <Message>), BuildMsSqlOutbox, serviceLifetime));
            brighterBuilder.Services.Add(new ServiceDescriptor(typeof(IAmAnOutboxAsync <Message>), BuildMsSqlOutbox, serviceLifetime));

            return(brighterBuilder);
        }
示例#7
0
        public static IBrighterBuilder UseDynamoDbOutbox(
            this IBrighterBuilder brighterBuilder, IAmazonDynamoDB connection, DynamoDbConfiguration configuration, ServiceLifetime serviceLifetime = ServiceLifetime.Singleton)
        {
            brighterBuilder.Services.AddSingleton <DynamoDbConfiguration>(configuration);
            brighterBuilder.Services.AddSingleton <IAmazonDynamoDB>(connection);

            brighterBuilder.Services.Add(new ServiceDescriptor(typeof(IAmAnOutboxSync <Message>), BuildDynamoDbOutbox, serviceLifetime));
            brighterBuilder.Services.Add(new ServiceDescriptor(typeof(IAmAnOutboxAsync <Message>), BuildDynamoDbOutbox, serviceLifetime));

            return(brighterBuilder);
        }
示例#8
0
        /// <summary>
        /// Use a timer based outbox sweeper as a Hosted Service.
        /// </summary>
        /// <param name="brighterBuilder">The Brighter Builder</param>
        /// <param name="timedOutboxSweeperOptionsAction">Configuration actions for the Timed outbox Sweeper <see cref="TimedOutboxSweeper"/></param>
        /// <returns>The Brighter Builder</returns>
        public static IBrighterBuilder UseOutboxSweeper(this IBrighterBuilder brighterBuilder,
                                                        Action <TimedOutboxSweeperOptions> timedOutboxSweeperOptionsAction = null)
        {
            var options = new TimedOutboxSweeperOptions();

            timedOutboxSweeperOptionsAction?.Invoke(options);

            brighterBuilder.Services.AddSingleton <TimedOutboxSweeperOptions>(options);
            brighterBuilder.Services.AddHostedService <TimedOutboxSweeper>();
            return(brighterBuilder);
        }
示例#9
0
        /// <summary>
        /// Use an external Brighter Outbox to store messages Posted to another process (evicts based on age and size).
        /// Advantages: By using the same Db to store both any state changes for your app, and outgoing messages you can create a transaction that spans both
        ///  your state change and writing to an outbox [use DepositPost to store]. Then a sweeper process can look for message not flagged as sent and send them.
        ///  For low latency just send after the transaction with ClearOutbox, for higher latency just let the sweeper run in the background.
        ///  The outstanding messages dispatched this way can be sent from any producer that runs a sweeper process and so it not tied to the lifetime of the
        ///  producer, offering guaranteed, at least once, delivery.
        ///  NOTE: there may be a database specific Use*OutBox available. If so, use that in preference to this generic method
        /// If not null, registers singletons with the service collection :-
        ///  - IAmAnOutboxSync - what messages have we posted
        ///  - ImAnOutboxAsync - what messages have we posted (async pipeline compatible)
        /// </summary>
        /// <param name="brighterBuilder">The Brighter builder to add this option to</param>
        /// <param name="outbox">The outbox provider - if your outbox supports both sync and async options, just provide this and we will register both</param>
        /// <returns></returns>
        public static IBrighterBuilder UseExternalOutbox(this IBrighterBuilder brighterBuilder, IAmAnOutbox <Message> outbox = null)
        {
            if (outbox is IAmAnOutboxSync <Message> )
            {
                brighterBuilder.Services.Add(new ServiceDescriptor(typeof(IAmAnOutboxSync <Message>), _ => outbox, ServiceLifetime.Singleton));
            }

            if (outbox is IAmAnOutboxAsync <Message> )
            {
                brighterBuilder.Services.Add(new ServiceDescriptor(typeof(IAmAnOutboxAsync <Message>), _ => outbox, ServiceLifetime.Singleton));
            }

            return(brighterBuilder);
        }
示例#10
0
        /// <summary>
        /// Uses an external Brighter Inbox to record messages received to allow "once only" or diagnostics (how did we get here?)
        /// Advantages: by using an external inbox then you can share "once only" across multiple threads/processes and support a competing consumer
        /// model; an internal inbox is useful for testing but outside of single consumer scenarios won't work as intended
        /// If not null, registers singletons with the service collecion :-
        ///  - IAmAnInboxSync - what messages have we received
        ///  - IAmAnInboxAsync - what messages have we received (async pipeline compatible)
        /// </summary>
        /// <param name="brighterBuilder">Extension method to support a fluent interface</param>
        /// <param name="inbox">The external inbox to use</param>
        /// <param name="inboxConfiguration">If this is null, configure by hand, if not, will auto-add inbox to handlers</param>
        /// <returns></returns>
        public static IBrighterBuilder UseExternalInbox(
            this IBrighterBuilder brighterBuilder,
            IAmAnInbox inbox, InboxConfiguration inboxConfiguration = null,
            ServiceLifetime serviceLifetime = ServiceLifetime.Scoped)
        {
            if (inbox is IAmAnInboxSync)
            {
                brighterBuilder.Services.Add(new ServiceDescriptor(typeof(IAmAnInboxSync), _ => inbox, serviceLifetime));
            }

            if (inbox is IAmAnInboxAsync)
            {
                brighterBuilder.Services.Add(new ServiceDescriptor(typeof(IAmAnInboxAsync), _ => inbox, serviceLifetime));
            }

            if (inboxConfiguration != null)
            {
                brighterBuilder.Services.AddSingleton <InboxConfiguration>(inboxConfiguration);
            }

            return(brighterBuilder);
        }
        /// <summary>
        /// Use this transaction provider to ensure that the Outbox and the Entity Store are correct
        /// </summary>
        /// <param name="brighterBuilder">Allows extension method</param>
        /// <param name="connectionProvider">What is the type of the connection provider. Must implement interface IPostgreSqlTransactionConnectionProvider</param>
        /// <param name="serviceLifetime">What is the lifetime of registered interfaces</param>
        /// <returns>Allows fluent syntax</returns>
        /// This is paired with Use Outbox (above) when required
        /// Registers the following
        /// -- IAmABoxTransactionConnectionProvider: the provider of a connection for any existing transaction
        public static IBrighterBuilder UsePostgreSqlTransactionConnectionProvider(
            this IBrighterBuilder brighterBuilder, Type connectionProvider,
            ServiceLifetime serviceLifetime = ServiceLifetime.Scoped)
        {
            if (brighterBuilder is null)
            {
                throw new ArgumentNullException($"{nameof(brighterBuilder)} cannot be null.", nameof(brighterBuilder));
            }

            if (connectionProvider is null)
            {
                throw new ArgumentNullException($"{nameof(connectionProvider)} cannot be null.", nameof(connectionProvider));
            }

            if (!typeof(IPostgreSqlTransactionConnectionProvider).IsAssignableFrom(connectionProvider))
            {
                throw new Exception($"Unable to register provider of type {connectionProvider.GetType().Name}. Class does not implement interface {nameof(IPostgreSqlTransactionConnectionProvider)}.");
            }

            brighterBuilder.Services.Add(new ServiceDescriptor(typeof(IAmABoxTransactionConnectionProvider), connectionProvider, serviceLifetime));

            return(brighterBuilder);
        }
示例#12
0
 /// <summary>
 /// Configure a Feature Switch registry to control handlers to be feature switched at runtime
 /// </summary>
 /// <param name="brighterBuilder">The Brighter builder to add this option to</param>
 /// <param name="featureSwitchRegistry">The registry for handler Feature Switches</param>
 /// <returns>The Brighter builder to allow chaining of requests</returns>
 public static IBrighterBuilder UseFeatureSwitches(this IBrighterBuilder brighterBuilder, IAmAFeatureSwitchRegistry featureSwitchRegistry)
 {
     brighterBuilder.Services.AddSingleton(featureSwitchRegistry);
     return(brighterBuilder);
 }