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, }; }
public DataSourceDependentMatcher( EndpointDataSource dataSource, Func <MatcherBuilder> matcherBuilderFactory) { _matcherBuilderFactory = matcherBuilderFactory; _cache = new DataSourceDependentCache <Matcher>(dataSource, CreateMatcher); _cache.EnsureInitialized(); }
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(); }
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; }
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_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 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 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; }
public RouteValuesAddressScheme(EndpointDataSource dataSource) { _cache = new DataSourceDependentCache <StateEntry>(dataSource, Initialize); }
public EndpointNameAddressScheme(EndpointDataSource dataSource) { _cache = new DataSourceDependentCache <Dictionary <string, Endpoint[]> >(dataSource, Initialize); }