public DefaultLinkGenerator(
            ParameterPolicyFactory parameterPolicyFactory,
            EndpointDataSource dataSource,
            ObjectPool <UriBuildingContext> uriBuildingContextPool,
            IOptions <RouteOptions> routeOptions,
            ILogger <DefaultLinkGenerator> logger,
            IServiceProvider serviceProvider)
        {
            _parameterPolicyFactory = parameterPolicyFactory;
            _uriBuildingContextPool = uriBuildingContextPool;
            _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,
            };
        }
示例#2
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);
        }
示例#3
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);
        }
示例#4
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);
        }
示例#5
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);
        }
示例#6
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
        }
 public RouteValuesAddressScheme(EndpointDataSource dataSource)
 {
     _cache = new DataSourceDependentCache <StateEntry>(dataSource, Initialize);
 }
示例#8
0
 public EndpointNameAddressScheme(EndpointDataSource dataSource)
 {
     _cache = new DataSourceDependentCache <Dictionary <string, Endpoint[]> >(dataSource, Initialize);
 }