예제 #1
0
        private async Task <TAggregate> GetByIdOrDefaultAsync <TAggregate>(string aggregateId, int version)
            where TAggregate : class, IAggregateRoot, new()
        {
            if (version <= 0)
            {
                throw new InvalidOperationException("Cannot get version <= 0");
            }

            var        streamName = $"{typeof(TAggregate).Name}:{aggregateId}";
            TAggregate aggregate  = new TAggregate
            {
                Version = -1
            };

            RedisValue value = await Policies.RedisValueFallbackPolicy.ExecuteAsync(() => _cache.StringGetAsync(streamName));

            if (value.HasValue)
            {
                aggregate = JsonSerializer.Deserialize <TAggregate>(value);
            }

            long sliceStart = aggregate.Version + 1;

            EventStoreClient.ReadStreamResult stream = _eventStoreClient.ReadStreamAsync(Direction.Forwards, streamName, StreamPosition.FromInt64(sliceStart));

            if (await stream.ReadState == ReadState.StreamNotFound)
            {
                return(null);
            }

            await foreach (var @event in stream)
            {
                object eventObject      = DeserializeEvent(@event.Event.Metadata, @event.Event.Data);
                Type   applyType        = typeof(IApply <>).MakeGenericType(eventObject.GetType());
                var    isAssignableFrom = applyType.IsAssignableFrom(aggregate.GetType());
                if (isAssignableFrom)
                {
                    ((dynamic)aggregate).Apply((dynamic)eventObject);
                }
                aggregate.Version++;
            }

            aggregate.Context = _context;
            return(aggregate);
        }
        public override StreamMetadata Read(ref Utf8JsonReader reader, Type typeToConvert,
                                            JsonSerializerOptions options)
        {
            int?           maxCount = null;
            TimeSpan?      maxAge = null, cacheControl = null;
            StreamPosition?truncateBefore = null;
            StreamAcl?     acl            = null;

            using var stream = new MemoryStream();
            using var customMetadataWriter = new Utf8JsonWriter(stream);

            if (reader.TokenType != JsonTokenType.StartObject)
            {
                throw new InvalidOperationException();
            }

            customMetadataWriter.WriteStartObject();

            while (reader.Read())
            {
                if (reader.TokenType == JsonTokenType.EndObject)
                {
                    break;
                }

                if (reader.TokenType != JsonTokenType.PropertyName)
                {
                    throw new InvalidOperationException();
                }

                switch (reader.GetString())
                {
                case SystemMetadata.MaxCount:
                    if (!reader.Read())
                    {
                        throw new InvalidOperationException();
                    }

                    maxCount = reader.GetInt32();
                    break;

                case SystemMetadata.MaxAge:
                    if (!reader.Read())
                    {
                        throw new InvalidOperationException();
                    }

                    var int64 = reader.GetInt64();
                    maxAge = TimeSpan.FromSeconds(int64);
                    break;

                case SystemMetadata.CacheControl:
                    if (!reader.Read())
                    {
                        throw new InvalidOperationException();
                    }

                    cacheControl = TimeSpan.FromSeconds(reader.GetInt64());
                    break;

                case SystemMetadata.TruncateBefore:
                    if (!reader.Read())
                    {
                        throw new InvalidOperationException();
                    }

                    var value = reader.GetInt64();
                    truncateBefore = value == long.MaxValue
                                                        ? StreamPosition.End
                                                        : StreamPosition.FromInt64(value);
                    break;

                case SystemMetadata.Acl:
                    if (!reader.Read())
                    {
                        throw new InvalidOperationException();
                    }

                    acl = StreamAclJsonConverter.Instance.Read(ref reader, typeof(StreamAcl), options);
                    break;

                default:
                    customMetadataWriter.WritePropertyName(reader.GetString() !);
                    reader.Read();
                    switch (reader.TokenType)
                    {
                    case JsonTokenType.Comment:
                        customMetadataWriter.WriteCommentValue(reader.GetComment());
                        break;

                    case JsonTokenType.String:
                        customMetadataWriter.WriteStringValue(reader.GetString());
                        break;

                    case JsonTokenType.Number:
                        customMetadataWriter.WriteNumberValue(reader.GetDouble());
                        break;

                    case JsonTokenType.True:
                    case JsonTokenType.False:
                        customMetadataWriter.WriteBooleanValue(reader.GetBoolean());
                        break;

                    case JsonTokenType.Null:
                        reader.Read();
                        customMetadataWriter.WriteNullValue();
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }

                    break;
                }
            }

            customMetadataWriter.WriteEndObject();
            customMetadataWriter.Flush();

            stream.Position = 0;

            return(new StreamMetadata(maxCount, maxAge, truncateBefore, cacheControl, acl,
                                      JsonDocument.Parse(stream)));
        }
        public static StreamPosition ParseStreamPosition(this ReadOnlyMemory <byte> json)
        {
            var checkPoint = json.ParseJson <string>();

            return(StreamPosition.FromInt64(int.Parse(checkPoint)));
        }