Beispiel #1
0
        public void Reset_MustNotSupportedException_Ok()
        {
            // Данные для теста
            var items = TreeItemHelper.Generate_ForDisposeTest();

            // Подсчёт вызовов
            var counter = new Counter();

            // Тестовые итераторы
            var head = new CustomEnumerable(items.Where(a => a.ParentId == 0), counter);                                                                    // 1 call = 1 disposing

            IEnumerable <TreeItem> GetChildren(TreeItem item) => new CustomEnumerable(items.Where(a => a.ParentId == item.Id).OrderBy(a => a.Id), counter); // 4 elements = 5 calls = 5 disposing (try get subelements at Id=5)

            // Шаблон формирования дерева с использованием итератора с контекстом
            using (var enumerator = new TreeEnumerator <TreeItem>(head, GetChildren))
            {
                int i = 0;
                while (enumerator.MoveNext())
                {
                    // i = 0 - current=head
                    // i = 1 - current=sub 1 head 1
                    // i = 2 - current=sub 1 head 2
                    // i = 3 - current=sub 1 head 3
                    // i = 4 - current=sub 1 head 4

                    if (i == 4)
                    {
                        // enumerator has stack with 5 elements
                        Assert.Throws <NotSupportedException>(() => enumerator.Reset());
                        break;
                    }

                    i++;
                }
            }
        }
Beispiel #2
0
        public void Dispose_MustBeExecuting_Ok()
        {
            // Данные для теста
            var items = TreeItemHelper.Generate_ForDisposeTest();

            // Подсчёт вызовов
            var counter = new Counter();

            // Тестовые итераторы
            var head = new CustomEnumerable(items.Where(a => a.ParentId == 0), counter);                                                                    // 1 call = 1 disposing

            IEnumerable <TreeItem> GetChildren(TreeItem item) => new CustomEnumerable(items.Where(a => a.ParentId == item.Id).OrderBy(a => a.Id), counter); // 4 elements = 5 calls = 5 disposing (try get subelements at Id=5)

            // Шаблон формирования дерева с использованием итератора с контекстом
            using (var enumerator = new TreeEnumerator <TreeItem>(head, GetChildren))
            {
                while (enumerator.MoveNext())
                {
                }
            }

            // total 6 calls
            Assert.Equal(6, counter.DisposeCount);
        }
Beispiel #3
0
        public override async Task MatchAsync(HttpContext httpContext, IEndpointFeature feature)
        {
            if (httpContext == null)
            {
                throw new ArgumentNullException(nameof(httpContext));
            }

            if (feature == null)
            {
                throw new ArgumentNullException(nameof(feature));
            }

            var values = new RouteValueDictionary();

            feature.Values = values;

            var cache = _cache.Value;

            for (var i = 0; i < cache.Length; i++)
            {
                var tree      = cache[i];
                var tokenizer = new PathTokenizer(httpContext.Request.Path);

                var treenumerator = new TreeEnumerator(tree.Root, tokenizer);

                while (treenumerator.MoveNext())
                {
                    var node = treenumerator.Current;
                    foreach (var item in node.Matches)
                    {
                        var entry   = item.Entry;
                        var matcher = item.TemplateMatcher;

                        values.Clear();
                        if (!matcher.TryMatch(httpContext.Request.Path, values))
                        {
                            continue;
                        }

                        Log.MatchedTemplate(_logger, httpContext, entry.RouteTemplate);

                        if (!MatchConstraints(httpContext, values, entry.Constraints))
                        {
                            continue;
                        }

                        await SelectEndpointAsync(httpContext, feature, (MatcherEndpoint[])entry.Tag);

                        if (feature.Endpoint != null)
                        {
                            if (feature.Endpoint is MatcherEndpoint endpoint)
                            {
                                foreach (var kvp in endpoint.Values)
                                {
                                    if (!feature.Values.ContainsKey(kvp.Key))
                                    {
                                        feature.Values[kvp.Key] = kvp.Value;
                                    }
                                }
                            }

                            return;
                        }
                    }
                }
            }
        }
Beispiel #4
0
    public async Task RouteAsync(RouteContext context)
    {
        foreach (var tree in _trees)
        {
            var tokenizer = new PathTokenizer(context.HttpContext.Request.Path);
            var root      = tree.Root;

            var treeEnumerator = new TreeEnumerator(root, tokenizer);

            // Create a snapshot before processing the route. We'll restore this snapshot before running each
            // to restore the state. This is likely an "empty" snapshot, which doesn't allocate.
            var snapshot = context.RouteData.PushState(router: null, values: null, dataTokens: null);

            while (treeEnumerator.MoveNext())
            {
                var node = treeEnumerator.Current;
                foreach (var item in node.Matches)
                {
                    var entry   = item.Entry;
                    var matcher = item.TemplateMatcher;

                    try
                    {
                        if (!matcher.TryMatch(context.HttpContext.Request.Path, context.RouteData.Values))
                        {
                            continue;
                        }

                        if (!RouteConstraintMatcher.Match(
                                entry.Constraints,
                                context.RouteData.Values,
                                context.HttpContext,
                                this,
                                RouteDirection.IncomingRequest,
                                _constraintLogger))
                        {
                            continue;
                        }

                        Log.RequestMatchedRoute(_logger, entry.RouteName, entry.RouteTemplate.TemplateText);
                        context.RouteData.Routers.Add(entry.Handler);

                        await entry.Handler.RouteAsync(context);

                        if (context.Handler != null)
                        {
                            return;
                        }
                    }
                    finally
                    {
                        if (context.Handler == null)
                        {
                            // Restore the original values to prevent polluting the route data.
                            snapshot.Restore();
                        }
                    }
                }
            }
        }
    }