コード例 #1
0
        public static MethodSlot[] FindInvalidMethods(Type projectionType, params MethodCollection[] collections)
        {
            var methodNames = collections.SelectMany(x => x.MethodNames).Distinct().ToArray();

            var invalidMethods = projectionType.GetMethods(BindingFlags.Public | BindingFlags.Instance)
                                 .Where(x => !x.HasAttribute <MartenIgnoreAttribute>())
                                 .Where(x => x.DeclaringType.Assembly != typeof(MethodCollection).Assembly)
                                 .Where(x => x.DeclaringType != typeof(object))
                                 .Where(x => !methodNames.Contains(x.Name))
                                 .Select(x => MethodSlot.InvalidMethodName(x, methodNames))
                                 .ToList();

            foreach (var collection in collections)
            {
                // We won't validate the methods that come through inline Lambdas
                foreach (var method in collection.Methods)
                {
                    method.Validate(collection);
                    collection.validateMethod(method); // hook for unusual rules
                }

                invalidMethods.AddRange(collection.Methods.Where(x => x.Errors.Any()));
            }

            return(invalidMethods.ToArray());
        }
コード例 #2
0
 internal override void validateMethod(MethodSlot method)
 {
     if (!method.Method.GetParameters().Any())
     {
         method.AddError($"ShouldDelete() requires at least one argument (the event type, the aggregate type, or IQuerySession)");
     }
 }
コード例 #3
0
 internal override void validateMethod(MethodSlot method)
 {
     if (!method.DeclaredByAggregate && method.Method.GetParameters().All(x => x.ParameterType != AggregateType))
     {
         method.AddError($"Aggregate type '{AggregateType.FullNameInCode()}' is required as a parameter");
     }
 }
コード例 #4
0
        public void AddLambda <T>(T lambda, Type eventType)
        {
            if (eventType == null)
            {
                throw new ArgumentNullException(nameof(eventType));
            }

            if (eventType.IsGenericType && eventType.Closes(typeof(IEvent <>)))
            {
                eventType = eventType.GetGenericArguments().Single();
            }

            var name   = LambdaName + (++_lambdaNumber).ToString();
            var method = lambda.GetType().GetMethod("Invoke");
            var setter = new Setter(typeof(T), name)
            {
                InitialValue = lambda
            };
            var slot = new MethodSlot(setter, method, eventType);

            Methods.Add(slot);

            if (method.IsAsync())
            {
                IsAsync = true;
            }
        }
コード例 #5
0
ファイル: MethodSlot.cs プロジェクト: seanswalling/marten
        public static MethodSlot InvalidMethodName(MethodInfo methodInfo, string[] methodNames)
        {
            var slot = new MethodSlot(methodInfo, null);

            slot._errors.Add($"Unrecognized method name '{methodInfo.Name}'. Either mark with [MartenIgnore] or use one of {methodNames.Select(x => $"'{x}'").Join(", ")}");

            return(slot);
        }
コード例 #6
0
 public ApplyMethodCall(MethodSlot slot) : base(slot.HandlerType, (MethodInfo)slot.Method)
 {
     EventType = slot.EventType;
     if (slot.Setter != null)
     {
         Target = slot.Setter;
     }
 }
コード例 #7
0
 public MaybeDeleteFrame(MethodSlot slot) : base(slot.Method.As <MethodInfo>().IsAsync())
 {
     EventType = slot.EventType;
     Maybe     = new MethodCall(slot.HandlerType, (MethodInfo)slot.Method)
     {
         Target = slot.Setter
     };
 }
コード例 #8
0
 public ShouldDeleteFrame(MethodSlot slot) : base(slot.Method.As <MethodInfo>().IsAsync())
 {
     EventType = slot.EventType;
     Maybe     = new MethodCall(slot.HandlerType, (MethodInfo)slot.Method)
     {
         Target = slot.Setter
     };
     Maybe.ReturnVariable.OverrideName(Maybe.ReturnVariable.Usage + ++_number);
 }
コード例 #9
0
 public CreateAggregateFrame(MethodSlot slot) : base(slot.HandlerType, (MethodInfo)slot.Method)
 {
     ReturnAction = ReturnAction.Return;
     EventType    = slot.EventType;
     if (slot.Setter != null)
     {
         Target = slot.Setter;
     }
 }
コード例 #10
0
 public MaybeDeleteFrame(Type aggregateType, Type identityType, MethodSlot slot) : base(slot.Method.As <MethodInfo>().IsAsync())
 {
     _aggregateType = aggregateType;
     _identityType  = identityType;
     EventType      = slot.EventType;
     Maybe          = new MethodCall(slot.HandlerType, (MethodInfo)slot.Method)
     {
         Target = slot.Setter
     };
 }
コード例 #11
0
        private void addMethodSlot(MethodInfo method, bool declaredByAggregate)
        {
            if (method.IsPublic)
            {
                var slot = new MethodSlot(method, AggregateType)
                {
                    HandlerType         = declaredByAggregate ? AggregateType : ProjectionType,
                    DeclaredByAggregate = declaredByAggregate
                };
                Methods.Add(slot);
            }
            else
            {
                var parameterTypes = new List <Type>();
                if (declaredByAggregate)
                {
                    parameterTypes.Add(AggregateType);
                }
                else
                {
                    parameterTypes.Add(ProjectionType);
                }

                parameterTypes.AddRange(method.GetParameters().Select(x => x.ParameterType));

                var parameters = parameterTypes.Select(Expression.Parameter).ToArray();


                Type baseType = null;
                if (method.ReturnType == typeof(void))
                {
                    baseType = _actionBaseTypes[parameterTypes.Count];
                }
                else
                {
                    parameterTypes.Add(method.ReturnType);
                    baseType = _funcBaseTypes[parameterTypes.Count];
                }


                var lambdaType = baseType.MakeGenericType(parameterTypes.ToArray());
                var loaderType = typeof(LambdaLoader <>).MakeGenericType(lambdaType);
                var loader     = (ILambdaLoader)Activator.CreateInstance(loaderType);
                loader.Add(this, method, AggregateType, parameters);
            }
        }
コード例 #12
0
        public CreateMethodCollection(Type projectionType, Type aggregateType) : base(MethodName, projectionType, aggregateType)
        {
            _validArgumentTypes.Add(typeof(IQuerySession));

            _validReturnTypes.Fill(aggregateType);
            _validReturnTypes.Add(typeof(Task <>).MakeGenericType(aggregateType));

            var constructors = aggregateType
                               .GetConstructors()
                               .Where(x => x.GetParameters().Length == 1);

            foreach (var constructor in constructors)
            {
                var slot = new MethodSlot(constructor, projectionType, aggregateType);
                Methods.Add(slot);
            }
        }
コード例 #13
0
 public override IEventHandlingFrame CreateEventTypeHandler(Type aggregateType,
                                                            IDocumentMapping aggregateMapping, MethodSlot slot)
 {
     return(new ApplyMethodCall(slot));
 }
コード例 #14
0
 public override IEventHandlingFrame CreateEventTypeHandler(Type aggregateType,
                                                            IDocumentMapping aggregateMapping, MethodSlot slot)
 {
     return(new ShouldDeleteFrame(slot));
 }
コード例 #15
0
        public override IEventHandlingFrame CreateEventTypeHandler(Type aggregateType,
                                                                   DocumentMapping aggregateMapping, MethodSlot slot)
        {
            if (slot.Method is ConstructorInfo)
            {
                return(new AggregateConstructorFrame(slot));
            }

            return(new CreateAggregateFrame(slot));
        }
コード例 #16
0
 internal override void validateMethod(MethodSlot method)
 {
     // Nothing, no special rules
 }
コード例 #17
0
 public AggregateConstructorFrame(MethodSlot slot)
 {
     _slot    = slot;
     _argType = slot.Method.GetParameters().Single().ParameterType;
 }
コード例 #18
0
 internal abstract void validateMethod(MethodSlot method);
コード例 #19
0
 public abstract IEventHandlingFrame CreateEventTypeHandler(Type aggregateType,
                                                            IDocumentMapping aggregateMapping, MethodSlot slot);
コード例 #20
0
 public override IEventHandlingFrame CreateEventTypeHandler(Type aggregateType,
                                                            DocumentMapping aggregateMapping, MethodSlot slot)
 {
     return(new MaybeDeleteFrame(aggregateType, aggregateMapping.IdType, slot));
 }