public DefaultLinkGenerator(
        TemplateBinderFactory binderFactory,
        EndpointDataSource dataSource,
        IOptions <RouteOptions> routeOptions,
        ILogger <DefaultLinkGenerator> logger,
        IServiceProvider serviceProvider)
    {
        _binderFactory   = binderFactory;
        _logger          = logger;
        _serviceProvider = serviceProvider;

        // We cache TemplateBinder instances per-Endpoint for performance, but we want to wipe out
        // that cache is the endpoints change so that we don't allow unbounded memory growth.
        _cache = new DataSourceDependentCache <ConcurrentDictionary <RouteEndpoint, TemplateBinder> >(dataSource, (_) =>
        {
            // We don't eagerly fill this cache because there's no real reason to. Unlike URL matching, we don't
            // need to build a big data structure up front to be correct.
            return(new ConcurrentDictionary <RouteEndpoint, TemplateBinder>());
        });

        // Cached to avoid per-call allocation of a delegate on lookup.
        _createTemplateBinder = CreateTemplateBinder;

        _globalLinkOptions = new LinkOptions()
        {
            AppendTrailingSlash   = routeOptions.Value.AppendTrailingSlash,
            LowercaseQueryStrings = routeOptions.Value.LowercaseQueryStrings,
            LowercaseUrls         = routeOptions.Value.LowercaseUrls,
        };
    }
Beispiel #2
0
        public DataSourceDependentMatcher(
            EndpointDataSource dataSource,
            Func <MatcherBuilder> matcherBuilderFactory)
        {
            _matcherBuilderFactory = matcherBuilderFactory;

            _cache = new DataSourceDependentCache <Matcher>(dataSource, CreateMatcher);
            _cache.EnsureInitialized();
        }
Beispiel #3
0
        public DynamicControllerEndpointSelector(EndpointDataSource dataSource)
        {
            if (dataSource == null)
            {
                throw new ArgumentNullException(nameof(dataSource));
            }

            _cache = new DataSourceDependentCache <ActionSelectionTable <Endpoint> >(dataSource, Initialize);
        }
        // Exposed for tests. We need to accept a more specific type in the constructor for DI
        // to work.
        protected DynamicPageEndpointSelector(EndpointDataSource dataSource)
        {
            if (dataSource == null)
            {
                throw new ArgumentNullException(nameof(dataSource));
            }

            _dataSource = dataSource;
            _cache      = new DataSourceDependentCache <ActionSelectionTable <Endpoint> >(dataSource, Initialize);
        }
 public AuthorizationPolicyCache(EndpointDataSource dataSource)
 {
     // We cache AuthorizationPolicy instances per-Endpoint for performance, but we want to wipe out
     // that cache if the endpoints change so that we don't allow unbounded memory growth.
     _policyCache = new DataSourceDependentCache <ConcurrentDictionary <Endpoint, AuthorizationPolicy> >(dataSource, (_) =>
     {
         // We don't eagerly fill this cache because there's no real reason to.
         return(new ConcurrentDictionary <Endpoint, AuthorizationPolicy>());
     });
     _policyCache.EnsureInitialized();
 }
Beispiel #6
0
        public DataSourceDependentMatcher(
            EndpointDataSource dataSource,
            Lifetime lifetime,
            Func <MatcherBuilder> matcherBuilderFactory)
        {
            _matcherBuilderFactory = matcherBuilderFactory;

            _cache = new DataSourceDependentCache <Matcher>(dataSource, CreateMatcher);
            _cache.EnsureInitialized();

            // This will Dispose the cache when the lifetime is disposed, this allows
            // the service provider to manage the lifetime of the cache.
            lifetime.Cache = _cache;
        }
Beispiel #7
0
    public void Cache_CanDispose_WhenUninitialized()
    {
        // Arrange
        var count = 0;

        var dataSource = new DynamicEndpointDataSource();
        var cache      = new DataSourceDependentCache <string>(dataSource, (endpoints) =>
        {
            count++;
            return($"hello, {count}!");
        });

        // Act
        cache.Dispose();

        // Assert
        dataSource.AddEndpoint(null);
        Assert.Null(cache.Value);
    }
Beispiel #8
0
    public void Cache_DoesNotInitialize_WhenValueCalled()
    {
        // Arrange
        var called = false;

        var dataSource = new DynamicEndpointDataSource();
        var cache      = new DataSourceDependentCache <string>(dataSource, (endpoints) =>
        {
            called = true;
            return("hello, world!");
        });

        // Act
        GC.KeepAlive(cache.Value);

        // Assert
        Assert.False(called);
        Assert.Null(cache.Value);
    }
Beispiel #9
0
    public void Cache_Initializes_WhenEnsureInitializedCalled()
    {
        // Arrange
        var called = false;

        var dataSource = new DynamicEndpointDataSource();
        var cache      = new DataSourceDependentCache <string>(dataSource, (endpoints) =>
        {
            called = true;
            return("hello, world!");
        });

        // Act
        cache.EnsureInitialized();

        // Assert
        Assert.True(called);
        Assert.Equal("hello, world!", cache.Value);
    }
Beispiel #10
0
    public void Cache_CanDispose_WhenInitialized()
    {
        // Arrange
        var count = 0;

        var dataSource = new DynamicEndpointDataSource();
        var cache      = new DataSourceDependentCache <string>(dataSource, (endpoints) =>
        {
            count++;
            return($"hello, {count}!");
        });

        cache.EnsureInitialized();
        Assert.Equal("hello, 1!", cache.Value);

        // Act
        cache.Dispose();

        // Assert
        dataSource.AddEndpoint(null);
        Assert.Equal("hello, 1!", cache.Value); // Ignores update
    }
Beispiel #11
0
    public void Cache_Reinitializes_WhenDataSourceChanges()
    {
        // Arrange
        var count = 0;

        var dataSource = new DynamicEndpointDataSource();
        var cache      = new DataSourceDependentCache <string>(dataSource, (endpoints) =>
        {
            count++;
            return($"hello, {count}!");
        });

        cache.EnsureInitialized();
        Assert.Equal("hello, 1!", cache.Value);

        // Act
        dataSource.AddEndpoint(null);

        // Assert
        Assert.Equal(2, count);
        Assert.Equal("hello, 2!", cache.Value);
    }
Beispiel #12
0
    public DefaultLinkParser(
        ParameterPolicyFactory parameterPolicyFactory,
        EndpointDataSource dataSource,
        ILogger <DefaultLinkParser> logger,
        IServiceProvider serviceProvider)
    {
        _parameterPolicyFactory = parameterPolicyFactory;
        _logger          = logger;
        _serviceProvider = serviceProvider;

        // We cache RoutePatternMatcher instances per-Endpoint for performance, but we want to wipe out
        // that cache is the endpoints change so that we don't allow unbounded memory growth.
        _matcherCache = new DataSourceDependentCache <ConcurrentDictionary <RouteEndpoint, MatcherState> >(dataSource, (_) =>
        {
            // We don't eagerly fill this cache because there's no real reason to. Unlike URL matching, we don't
            // need to build a big data structure up front to be correct.
            return(new ConcurrentDictionary <RouteEndpoint, MatcherState>());
        });

        // Cached to avoid per-call allocation of a delegate on lookup.
        _createMatcher = CreateRoutePatternMatcher;
    }
Beispiel #13
0
 public RouteValuesAddressScheme(EndpointDataSource dataSource)
 {
     _cache = new DataSourceDependentCache <StateEntry>(dataSource, Initialize);
 }
 public EndpointNameAddressScheme(EndpointDataSource dataSource)
 {
     _cache = new DataSourceDependentCache <Dictionary <string, Endpoint[]> >(dataSource, Initialize);
 }