コード例 #1
0
        public static T _runCycle <T>(T source, List <EnsureHistoryItem> history)
            where T : class, IImmutable
        {
            var rootContext = new EnsureContext(source);

            var plan = _createPlan(rootContext);

            foreach (var step in plan)
            {
                var res = _callMethod(step.method, step.context);
                if (!ReferenceEquals(step.context.Entity, res))
                {
                    // Ensure made changes, so the cycle needs to restart
                    var changedSource = step.context.ApplyNewValue(res) as T;

                    if (history != null)
                    {
                        var item = new EnsureHistoryItem(
                            ensureMethod: step.method.Name,
                            before: source,
                            after: changedSource,
                            context: step.context
                            );
                        history.Add(item);
                    }
                    return(changedSource);
                }
            }

            return(source);
        }
コード例 #2
0
 public EnsureContext(object root)
 {
     _parent   = null;
     _entity   = root;
     _property = null;
     _index    = -1;
     _findTypeOfCurrent();
 }
コード例 #3
0
 public EnsureHistoryItem(
     string ensureMethod   = "",
     object before         = null,
     object after          = null,
     EnsureContext context = null)
 {
     EnsureMethod = ensureMethod;
     Before       = before;
     After        = after;
     Context      = context;
 }
コード例 #4
0
 public EnsureContext(EnsureContext parent, PropertyInfo property)
 {
     if (parent._type != CurrentType.Object)
     {
         throw new InvalidOperationException();
     }
     _parent   = parent;
     _index    = -1;
     _property = property;
     _entity   = property.AsGetter <object, object>().Invoke(_parent._entity);
     _findTypeOfCurrent();
 }
コード例 #5
0
        public EnsureContext(EnsureContext parent, int index)
        {
            if (parent._type != CurrentType.List)
            {
                throw new InvalidOperationException();
            }
            _parent   = parent;
            _index    = index;
            _property = null;

            var source = _parent._entity as IList;

            _entity = source[index];
            _findTypeOfCurrent();
        }
コード例 #6
0
        public static object _callMethod(MethodInfo method, EnsureContext context)
        {
            // the method should only be called if the conditions apply, so first we allow each condition to run and prevent calling the ensurer
            var conditions = _conditionsPerEnsurer[method];

            foreach (var condition in conditions)
            {
                var res = condition.Lambda(context);
                if (res != condition.ExpectedValue)
                {
                    return(context.Entity);  // return the original entity of he context
                }
            }

            // if we have got here, all conditions apply, so we can run the ensurer itself
            var lambda = _ensureLambdas[method];
            var result = lambda(context);

            return(result);
        }
コード例 #7
0
        public static IEnumerable <(int index, EnsureContext context, MethodInfo method)> _createPlan(EnsureContext rootContext)
        {
            var allContexts = rootContext.FlattenSubContexts();

            return(allContexts
                   .SelectMany(ctxt => _ensureMethodsForType(ctxt.Entity.GetType())
                               .Select(method => (context: ctxt, method: method)))
                   .Select((pair, index) => (index: index, context: pair.context, method: pair.method)));
        }