/// <inheritdoc />
        public async Task <IResult> Create(StructureIdentifier identifier,
                                           IDictionary <string, string> keys,
                                           IDictionary <string, string> variables)
        {
            _logger.LogDebug($"attempting to create new structure '{identifier}'");

            var structResult = await _domainObjectStore.ReplayObject(new ConfigStructure(identifier), identifier.ToString());

            if (structResult.IsError)
            {
                return(structResult);
            }

            var structure = structResult.Data;

            _logger.LogDebug("creating Structure");
            var result = structure.Create(keys, variables);

            if (result.IsError)
            {
                return(result);
            }

            _logger.LogDebug("validating resulting events");
            var errors = structure.Validate(_validators);

            if (errors.Any())
            {
                return(Result.Error("failed to validate generated DomainEvents",
                                    ErrorCode.ValidationFailed,
                                    errors.Values
                                    .SelectMany(_ => _)
                                    .ToList()));
            }

            _logger.LogDebug("writing generated events to ES");
            return(await structure.WriteRecordedEvents(_eventStore));
        }
        /// <inheritdoc />
        public async Task <IResult> DeleteVariables(StructureIdentifier identifier, ICollection <string> variablesToDelete)
        {
            _logger.LogDebug($"attempting to delete variables from structure '{identifier}'");

            var structResult = await _domainObjectStore.ReplayObject(new ConfigStructure(identifier), identifier.ToString());

            if (structResult.IsError)
            {
                return(structResult);
            }

            var structure = structResult.Data;

            _logger.LogDebug($"removing '{variablesToDelete.Count}' variables from '{identifier}' " +
                             $"at version '{structure.CurrentVersion}' / {structure.MetaVersion}");

            var updateResult = structure.DeleteVariables(variablesToDelete);

            if (updateResult.IsError)
            {
                return(updateResult);
            }

            _logger.LogDebug("validating resulting events");
            var errors = structure.Validate(_validators);

            if (errors.Any())
            {
                return(Result.Error("failed to validate generated DomainEvents",
                                    ErrorCode.ValidationFailed,
                                    errors.Values
                                    .SelectMany(_ => _)
                                    .ToList()));
            }

            return(await structure.WriteRecordedEvents(_eventStore));
        }
        /// <inheritdoc />
        public async Task <IResult <IDictionary <string, string> > > GetVariables(StructureIdentifier identifier, QueryRange range)
        {
            try
            {
                _logger.LogDebug($"retrieving variables of structure '{identifier}'");

                var structResult = await _domainObjectStore.ReplayObject(new ConfigStructure(identifier), identifier.ToString());

                if (structResult.IsError)
                {
                    return(Result.Error <IDictionary <string, string> >("no structure found with (" +
                                                                        $"{nameof(identifier.Name)}: {identifier.Name}; " +
                                                                        $"{nameof(identifier.Version)}: {identifier.Version}" +
                                                                        ")",
                                                                        ErrorCode.NotFound));
                }

                var structure = structResult.Data;

                _logger.LogDebug($"got structure at version '{structure.CurrentVersion}' / {structure.MetaVersion}");

                var result = structure.Variables
                             .OrderBy(v => v.Key)
                             .Skip(range.Offset)
                             .Take(range.Length)
                             .ToImmutableSortedDictionary(k => k.Key,
                                                          k => k.Value,
                                                          StringComparer.OrdinalIgnoreCase);

                return(Result.Success <IDictionary <string, string> >(result));
            }
            catch (Exception e)
            {
                _logger.LogError("failed to retrieve variables for structure " +
                                 $"({nameof(identifier.Name)}: {identifier.Name}; {nameof(identifier.Version)}: {identifier.Version}): {e}");

                return(Result.Error <IDictionary <string, string> >(
                           "failed to retrieve variables for structure " +
                           $"({nameof(identifier.Name)}: {identifier.Name}; {nameof(identifier.Version)}: {identifier.Version})",
                           ErrorCode.DbQueryError));
            }
        }