示例#1
0
        private GeneratedMethod buildDetermineOperationMethod()
        {
            var method = _inlineType.MethodFor(nameof(AggregationRuntime <string, string> .DetermineOperation));

            // This gets you the EventSlice aggregate Id

            method.DerivedVariables.Add(new Variable(_aggregateMapping.IdType, $"slice.{nameof(EventSlice<string, string>.Id)}"));
            method.DerivedVariables.Add(Variable.For <ITenant>($"slice.{nameof(EventSlice<string, string>.Tenant)}"));
            method.DerivedVariables.Add(Variable.For <ITenant>($"slice.{nameof(EventSlice<string, string>.Tenant)}"));
            method.DerivedVariables.Add(Variable.For <IEvent>("@event"));
            method.DerivedVariables.Add(Variable.For <IMartenSession>($"({typeof(IMartenSession).FullNameInCode()})session"));
            method.DerivedVariables.Add(Variable.For <IQuerySession>("session"));
            method.DerivedVariables.Add(
                Variable.For <IAggregateProjection>(nameof(AggregationRuntime <string, string> .Projection)));

            var createFrame = new CallCreateAggregateFrame(_createMethods);

            method.Frames.Add(new InitializeLiveAggregateFrame(typeof(T), _aggregateMapping.IdType, createFrame));

            method.Frames.Add(new MethodCall(_storageType, "SetIdentity"));

            var handlers = MethodCollection.AddEventHandling(typeof(T), _aggregateMapping, _applyMethods, _shouldDeleteMethods);
            var iterate  = new ForEachEventFrame((IReadOnlyList <Frame>)handlers);

            method.Frames.Add(iterate);
            return(method);
        }
示例#2
0
        private void buildInlineAggregationType()
        {
            var inlineBaseType =
                typeof(InlineAggregationBase <,>).MakeGenericType(typeof(T), _aggregateMapping.IdType);

            _inlineType = _assembly.AddType(GetType().NameInCode().Sanitize() + "InlineHandler", inlineBaseType);

            _createMethods.BuildCreateMethod(_inlineType, _aggregateMapping);

            _inlineType.AllInjectedFields.Add(new InjectedField(_storageType));
            _inlineType.AllInjectedFields.Add(new InjectedField(GetType()));

            var method = _inlineType.MethodFor(nameof(InlineAggregationBase <string, string> .DetermineOperation));

            // This gets you the EventSlice aggregate Id
            method.DerivedVariables.Add(Variable.For <Guid>($"slice.{nameof(EventSlice<string, string>.Id)}"));
            method.DerivedVariables.Add(Variable.For <string>($"slice.{nameof(EventSlice<string, string>.Id)}"));

            // TODO -- this is hokey. Just pass in ITenant?
            method.DerivedVariables.Add(Variable.For <ITenant>($"(({typeof(IMartenSession).FullNameInCode()})session).{nameof(IMartenSession.Tenant)}"));
            method.DerivedVariables.Add(Variable.For <IEvent>("@event"));
            method.DerivedVariables.Add(Variable.For <IMartenSession>($"({typeof(IMartenSession).FullNameInCode()})session"));
            method.DerivedVariables.Add(Variable.For <IQuerySession>("session"));
            method.DerivedVariables.Add(Variable.For <IAggregateProjection>(nameof(InlineAggregationBase <string, string> .Projection)));

            var sliceType =
                typeof(EventSlice <,>).MakeGenericType(_aggregateMapping.DocumentType, _aggregateMapping.IdType);

            if (DeleteEvents.Any())
            {
                method.Frames.Code($"if (Projection.{nameof(MatchesAnyDeleteType)}({{0}})) return {{1}}.{nameof(IDocumentStorage<string, string>.DeleteForId)}({{2}});", new Use(sliceType), new Use(_storageType), new Use(_aggregateMapping.IdType));
            }

            var createFrame = new CallCreateAggregateFrame(_createMethods);

            method.Frames.Add(new InitializeLiveAggregateFrame(typeof(T), _aggregateMapping.IdType, createFrame));

            method.Frames.Add(new MethodCall(_storageType, "SetIdentity"));

            var handlers = MethodCollection.AddEventHandling(typeof(T), _aggregateMapping, _applyMethods, _shouldDeleteMethods);
            var iterate  = new ForEachEventFrame((IReadOnlyList <Frame>)handlers);

            method.Frames.Add(iterate);

            var upsertMethod = typeof(IDocumentStorage <>).MakeGenericType(typeof(T)).GetMethod("Upsert");

            var upsert = new MethodCall(_storageType, upsertMethod)
            {
                ReturnAction = ReturnAction.Return
            };

            method.Frames.Add(upsert);

            _inlineType.Setters.AddRange(_applyMethods.Setters());
            _inlineType.Setters.AddRange(_createMethods.Setters());
            _inlineType.Setters.AddRange(_shouldDeleteMethods.Setters());
        }
示例#3
0
        private void buildDetermineOperationMethodForDaemonRunner(bool daemonBuilderIsAsync)
        {
            var methodName = daemonBuilderIsAsync ? "DetermineOperation" : "DetermineOperationSync";
            var method     = _asyncDaemonType.MethodFor(methodName);

            if (daemonBuilderIsAsync)
            {
                method.AsyncMode = AsyncMode.AsyncTask;
            }

            method.DerivedVariables.Add(Variable.For <ITenant>($"fragment.{nameof(StreamFragment<string, string>.Tenant)}"));
            method.DerivedVariables.Add(Variable.For <IEvent>("@event"));
            method.DerivedVariables.Add(Variable.For <IQuerySession>($"(({typeof(IQuerySession).FullNameInCode()})session)"));

            // At most, only one of these would be used
            method.DerivedVariables.Add(Variable.For <Guid>($"fragment.Id"));
            method.DerivedVariables.Add(Variable.For <string>($"fragment.Id"));

            var aggregate = new Variable(typeof(T),
                                         $"fragment.{nameof(StreamFragment<string, string>.Aggregate)}");

            method.DerivedVariables.Add(aggregate);

            var createFrame = new CallCreateAggregateFrame(_createMethods, aggregate)
            {
                FirstEventExpression = $"fragment.{nameof(StreamFragment<string, string>.Events)}[0]",
                Action = CreateAggregateAction.NullCoalesce
            };

            method.Frames.Add(createFrame);
            method.Frames.Add(new MethodCall(_storageType, "SetIdentity"));

            var handlers = MethodCollection.AddEventHandling(typeof(T), _aggregateMapping, _applyMethods, _shouldDeleteMethods);
            var iterate  = new ForEachEventFrame((IReadOnlyList <Frame>)handlers)
            {
                EventIteration = "fragment.Events"
            };

            method.Frames.Add(iterate);

            var upsertMethod = typeof(IDocumentStorage <>).MakeGenericType(typeof(T)).GetMethod("Upsert");

            var upsert = new MethodCall(_storageType, upsertMethod)
            {
                ReturnAction = ReturnAction.Return
            };

            method.Frames.Add(upsert);
        }
        private void buildLiveAggregationType()
        {
            var liveBaseType = _isAsync
                ? typeof(AsyncLiveAggregatorBase <>)
                : typeof(SyncLiveAggregatorBase <>);

            liveBaseType = liveBaseType.MakeGenericType(typeof(T));


            _liveType =
                _assembly.AddType(GetType().NameInCode().Sanitize() + "LiveAggregation", liveBaseType);

            var overrideMethodName = _isAsync ? "BuildAsync" : "Build";
            var buildMethod        = _liveType.MethodFor(overrideMethodName);

            buildMethod.DerivedVariables.Add(Variable.For <IQuerySession>("(IQuerySession)session"));

            buildMethod.Frames.Code("if (!events.Any()) return null;");

            buildMethod.Frames.Add(new DeclareAggregateFrame(typeof(T)));


            var callCreateAggregateFrame = new CallCreateAggregateFrame(_createMethods);

            // This is the existing snapshot passed into the LiveAggregator
            var snapshot = buildMethod.Arguments.Single(x => x.VariableType == typeof(T));

            callCreateAggregateFrame.CoalesceAssignTo(snapshot);

            buildMethod.Frames.Add(callCreateAggregateFrame);
            buildMethod.Frames.Add(new CallApplyAggregateFrame(_applyMethods)
            {
                InsideForEach = true
            });

            buildMethod.Frames.Return(typeof(T));

            _liveType.AllInjectedFields.Add(new InjectedField(GetType()));

            _createMethods.BuildCreateMethod(_liveType, _aggregateMapping);
            _applyMethods.BuildApplyMethod(_liveType, _aggregateMapping);

            _liveType.Setters.AddRange(_applyMethods.Setters());
            _liveType.Setters.AddRange(_createMethods.Setters());
            _liveType.Setters.AddRange(_shouldDeleteMethods.Setters());
        }