/// <summary>
        /// Initializes a new <see cref="FilesystemMessageQueueingService"/>
        /// </summary>
        /// <param name="options">Options affecting the behavior of the filesystem message queueing
        /// service</param>
        /// <remarks>
        /// <para>If a base directory is not specified then the base directory will default to a
        /// directory named <c>platibus\queues</c> beneath the current app domain base
        /// directory.  If the base directory does not exist it will be created in the
        /// <see cref="Init"/> method.</para>
        /// <para>If a security token service is not specified then a default implementation based
        /// on unsigned JWTs will be used.</para>
        /// </remarks>
        public FilesystemMessageQueueingService(FilesystemMessageQueueingOptions options)
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            _diagnosticService = options.DiagnosticService ?? DiagnosticService.DefaultInstance;

            var myBaseDirectory = options.BaseDirectory;

            if (myBaseDirectory == null)
            {
                var appdomainDirectory = AppDomain.CurrentDomain.BaseDirectory;
                myBaseDirectory = new DirectoryInfo(Path.Combine(appdomainDirectory, "platibus", "queues"));
            }
            _baseDirectory            = myBaseDirectory;
            _securityTokenService     = options.SecurityTokenService ?? new JwtSecurityTokenService();
            _messageEncryptionService = options.MessageEncryptionService;
        }
        /// <inheritdoc />
        /// <summary>
        /// Creates an initializes a <see cref="T:Platibus.IMessageQueueingService" />
        /// based on the provided <paramref name="configuration" />
        /// </summary>
        /// <param name="configuration">The journaling configuration
        /// element</param>
        /// <returns>Returns a task whose result is an initialized
        /// <see cref="T:Platibus.IMessageQueueingService" /></returns>
        public async Task <IMessageQueueingService> CreateMessageQueueingService(QueueingElement configuration)
        {
            var path = configuration.GetString("path");

            var securityTokenServiceFactory = new SecurityTokenServiceFactory();
            var securityTokenConfig         = configuration.SecurityTokens;
            var securityTokenService        = await securityTokenServiceFactory.InitSecurityTokenService(securityTokenConfig);

            var messageEncryptionServiceFactory = new MessageEncryptionServiceFactory();
            var messageEncryptionConfig         = configuration.Encryption;
            var messageEncryptionService        = await messageEncryptionServiceFactory.InitMessageEncryptionService(messageEncryptionConfig);

            var fsQueueingOptions = new FilesystemMessageQueueingOptions
            {
                BaseDirectory            = GetRootedDirectory(path),
                SecurityTokenService     = securityTokenService,
                MessageEncryptionService = messageEncryptionService
            };
            var fsQueueingService = new FilesystemMessageQueueingService(fsQueueingOptions);

            fsQueueingService.Init();
            return(fsQueueingService);
        }
        /// <inheritdoc />
        /// <summary>
        /// Creates an initializes a <see cref="T:Platibus.IMessageQueueingService" />
        /// based on the provided <paramref name="configuration" />
        /// </summary>
        /// <param name="configuration">The journaling configuration
        ///     element</param>
        /// <returns>Returns a task whose result is an initialized
        /// <see cref="T:Platibus.IMessageQueueingService" /></returns>
        public async Task <IMessageQueueingService> CreateMessageQueueingService(IConfiguration configuration)
        {
            var path = configuration?["path"];

            var securityTokenServiceFactory = new SecurityTokenServiceFactory();
            var securityTokenConfig         = configuration?.GetSection("securityTokens");
            var securityTokenService        = await securityTokenServiceFactory.InitSecurityTokenService(securityTokenConfig);

            var messageEncryptionServiceFactory = new MessageEncryptionServiceFactory();
            var messageEncryptionConfig         = configuration?.GetSection("encryption");
            var messageEncryptionService        = await messageEncryptionServiceFactory.InitMessageEncryptionService(messageEncryptionConfig);

            var fsQueueingOptions = new FilesystemMessageQueueingOptions()
            {
                BaseDirectory            = GetRootedDirectory(path),
                SecurityTokenService     = securityTokenService,
                MessageEncryptionService = messageEncryptionService
            };

            var fsQueueingService = new FilesystemMessageQueueingService(fsQueueingOptions);

            fsQueueingService.Init();
            return(fsQueueingService);
        }