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, }; }
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); }
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); }
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); }
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); }
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); }
public EndpointNameAddressScheme(EndpointDataSource dataSource) { _cache = new DataSourceDependentCache <Dictionary <string, Endpoint[]> >(dataSource, Initialize); }