Convert the static UriHelper into a service, IUriHelper, and inject where needed
This commit is contained in:
parent
68f6ede3a7
commit
82bcf9172a
|
|
@ -34,7 +34,7 @@ export const monoPlatform: Platform = {
|
||||||
|
|
||||||
const typeHandle = find_class(assemblyHandle, namespace, className);
|
const typeHandle = find_class(assemblyHandle, namespace, className);
|
||||||
if (!typeHandle) {
|
if (!typeHandle) {
|
||||||
throw new Error(`Could not find type "${className}'" in namespace "${namespace}" in assembly "${assemblyName}"`);
|
throw new Error(`Could not find type "${className}" in namespace "${namespace}" in assembly "${assemblyName}"`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const methodHandle = find_method(typeHandle, methodName, -1);
|
const methodHandle = find_method(typeHandle, methodName, -1);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { registerFunction } from '../Interop/RegisteredFunction';
|
import { registerFunction } from '../Interop/RegisteredFunction';
|
||||||
import { platform } from '../Environment';
|
import { platform } from '../Environment';
|
||||||
import { MethodHandle } from '../Platform/Platform';
|
import { MethodHandle } from '../Platform/Platform';
|
||||||
const registeredFunctionPrefix = 'Microsoft.AspNetCore.Blazor.Browser.Routing.UriHelper';
|
const registeredFunctionPrefix = 'Microsoft.AspNetCore.Blazor.Browser.Services.BrowserUriHelper';
|
||||||
let notifyLocationChangedMethod: MethodHandle;
|
let notifyLocationChangedMethod: MethodHandle;
|
||||||
let hasRegisteredEventListeners = false;
|
let hasRegisteredEventListeners = false;
|
||||||
|
|
||||||
|
|
@ -37,8 +37,8 @@ function handleInternalNavigation() {
|
||||||
if (!notifyLocationChangedMethod) {
|
if (!notifyLocationChangedMethod) {
|
||||||
notifyLocationChangedMethod = platform.findMethod(
|
notifyLocationChangedMethod = platform.findMethod(
|
||||||
'Microsoft.AspNetCore.Blazor.Browser',
|
'Microsoft.AspNetCore.Blazor.Browser',
|
||||||
'Microsoft.AspNetCore.Blazor.Browser.Routing',
|
'Microsoft.AspNetCore.Blazor.Browser.Services',
|
||||||
'UriHelper',
|
'BrowserUriHelper',
|
||||||
'NotifyLocationChanged'
|
'NotifyLocationChanged'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ using System.Reflection;
|
||||||
using Microsoft.AspNetCore.Blazor.Components;
|
using Microsoft.AspNetCore.Blazor.Components;
|
||||||
using Microsoft.AspNetCore.Blazor.Layouts;
|
using Microsoft.AspNetCore.Blazor.Layouts;
|
||||||
using Microsoft.AspNetCore.Blazor.RenderTree;
|
using Microsoft.AspNetCore.Blazor.RenderTree;
|
||||||
|
using Microsoft.AspNetCore.Blazor.Services;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Blazor.Browser.Routing
|
namespace Microsoft.AspNetCore.Blazor.Browser.Routing
|
||||||
{
|
{
|
||||||
|
|
@ -22,6 +23,8 @@ namespace Microsoft.AspNetCore.Blazor.Browser.Routing
|
||||||
string _baseUriPrefix;
|
string _baseUriPrefix;
|
||||||
string _locationAbsolute;
|
string _locationAbsolute;
|
||||||
|
|
||||||
|
[Inject] private IUriHelper UriHelper { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the assembly that should be searched, along with its referenced
|
/// Gets or sets the assembly that should be searched, along with its referenced
|
||||||
/// assemblies, for components matching the URI.
|
/// assemblies, for components matching the URI.
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
using Microsoft.AspNetCore.Blazor.Components;
|
using Microsoft.AspNetCore.Blazor.Components;
|
||||||
using Microsoft.AspNetCore.Blazor.RenderTree;
|
using Microsoft.AspNetCore.Blazor.RenderTree;
|
||||||
|
using Microsoft.AspNetCore.Blazor.Services;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
@ -32,6 +33,8 @@ namespace Microsoft.AspNetCore.Blazor.Browser.Routing
|
||||||
private string _hrefAbsolute;
|
private string _hrefAbsolute;
|
||||||
private IReadOnlyDictionary<string, object> _allAttributes;
|
private IReadOnlyDictionary<string, object> _allAttributes;
|
||||||
|
|
||||||
|
[Inject] private IUriHelper UriHelper { get; set; }
|
||||||
|
|
||||||
public void Init(RenderHandle renderHandle)
|
public void Init(RenderHandle renderHandle)
|
||||||
{
|
{
|
||||||
_renderHandle = renderHandle;
|
_renderHandle = renderHandle;
|
||||||
|
|
|
||||||
|
|
@ -2,28 +2,31 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using Microsoft.AspNetCore.Blazor.Browser.Interop;
|
using Microsoft.AspNetCore.Blazor.Browser.Interop;
|
||||||
|
using Microsoft.AspNetCore.Blazor.Services;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Blazor.Browser.Routing
|
namespace Microsoft.AspNetCore.Blazor.Browser.Services
|
||||||
{
|
{
|
||||||
// TODO: Make this not static, and wrap it in an interface that can be injected through DI.
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Helpers for working with URIs and navigation state.
|
/// Default browser implementation of <see cref="IUriHelper"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class UriHelper
|
public class BrowserUriHelper : IUriHelper
|
||||||
{
|
{
|
||||||
static readonly string _functionPrefix = typeof(UriHelper).FullName;
|
// Since there's only one browser (and hence only one navigation state), the internal state
|
||||||
|
// is all static. In typical usage the DI system will register BrowserUriHelper as a singleton
|
||||||
|
// so it makes no difference, but if you manually instantiate more than one BrowserUriHelper
|
||||||
|
// that's fine too - they will just share their internal state.
|
||||||
|
// This class will never be used during server-side prerendering, so we don't have thread-
|
||||||
|
// safety concerns due to the static state.
|
||||||
|
static readonly string _functionPrefix = typeof(BrowserUriHelper).FullName;
|
||||||
|
static bool _hasEnabledNavigationInterception;
|
||||||
static string _currentAbsoluteUri;
|
static string _currentAbsoluteUri;
|
||||||
|
static EventHandler<string> _onLocationChanged;
|
||||||
static string _baseUriString;
|
static string _baseUriString;
|
||||||
static Uri _baseUri;
|
static Uri _baseUri;
|
||||||
static EventHandler<string> _onLocationChanged;
|
|
||||||
static bool _hasEnabledNavigationInterception;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc />
|
||||||
/// An event that fires when the navigation location has changed.
|
public event EventHandler<string> OnLocationChanged
|
||||||
/// </summary>
|
|
||||||
public static event EventHandler<string> OnLocationChanged
|
|
||||||
{
|
{
|
||||||
add
|
add
|
||||||
{
|
{
|
||||||
|
|
@ -38,63 +41,34 @@ namespace Microsoft.AspNetCore.Blazor.Browser.Routing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc />
|
||||||
/// Gets the URI prefix that can be prepended before URI paths to produce an absolute URI.
|
public string GetBaseUriPrefix()
|
||||||
/// Typically this corresponds to the 'href' attribute on the document's <base> element.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The URI prefix.</returns>
|
|
||||||
public static string GetBaseUriPrefix()
|
|
||||||
{
|
{
|
||||||
EnsureBaseUriPopulated();
|
EnsureBaseUriPopulated();
|
||||||
return _baseUriString;
|
return _baseUriString;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void EnsureBaseUriPopulated()
|
/// <inheritdoc />
|
||||||
{
|
public string GetAbsoluteUri()
|
||||||
// The <base href> is fixed for the lifetime of the page, so just cache it
|
|
||||||
if (_baseUriString == null)
|
|
||||||
{
|
|
||||||
var baseUri = RegisteredFunction.InvokeUnmarshalled<string>(
|
|
||||||
$"{_functionPrefix}.getBaseURI");
|
|
||||||
_baseUriString = ToBaseUriPrefix(baseUri);
|
|
||||||
_baseUri = new Uri(_baseUriString);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the browser's current absolute URI.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The browser's current absolute URI.</returns>
|
|
||||||
public static string GetAbsoluteUri()
|
|
||||||
{
|
{
|
||||||
if (_currentAbsoluteUri == null)
|
if (_currentAbsoluteUri == null)
|
||||||
{
|
{
|
||||||
_currentAbsoluteUri = RegisteredFunction.InvokeUnmarshalled<string>(
|
_currentAbsoluteUri = RegisteredFunction.InvokeUnmarshalled<string>(
|
||||||
$"{_functionPrefix}.getLocationHref");
|
$"{_functionPrefix}.getLocationHref");
|
||||||
}
|
}
|
||||||
|
|
||||||
return _currentAbsoluteUri;
|
return _currentAbsoluteUri;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc />
|
||||||
/// Converts a relative URI into an absolute one.
|
public Uri ToAbsoluteUri(string relativeUri)
|
||||||
/// </summary>
|
|
||||||
/// <param name="relativeUri">The relative URI.</param>
|
|
||||||
/// <returns>The absolute URI.</returns>
|
|
||||||
public static Uri ToAbsoluteUri(string relativeUri)
|
|
||||||
{
|
{
|
||||||
EnsureBaseUriPopulated();
|
EnsureBaseUriPopulated();
|
||||||
return new Uri(_baseUri, relativeUri);
|
return new Uri(_baseUri, relativeUri);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc />
|
||||||
/// Given a base URI prefix (e.g., one previously returned by <see cref="GetBaseUriPrefix"/>),
|
public string ToBaseRelativePath(string baseUriPrefix, string absoluteUri)
|
||||||
/// converts an absolute URI into one relative to the base URI prefix.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="baseUriPrefix">The base URI prefix (e.g., previously returned by <see cref="GetBaseUriPrefix"/>).</param>
|
|
||||||
/// <param name="absoluteUri">An absolute URI that is within the space of the base URI prefix.</param>
|
|
||||||
/// <returns>A relative URI path.</returns>
|
|
||||||
public static string ToBaseRelativePath(string baseUriPrefix, string absoluteUri)
|
|
||||||
{
|
{
|
||||||
if (absoluteUri.Equals(baseUriPrefix, StringComparison.Ordinal))
|
if (absoluteUri.Equals(baseUriPrefix, StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
|
|
@ -117,6 +91,18 @@ namespace Microsoft.AspNetCore.Blazor.Browser.Routing
|
||||||
throw new ArgumentException($"The URI '{absoluteUri}' is not contained by the base URI '{baseUriPrefix}'.");
|
throw new ArgumentException($"The URI '{absoluteUri}' is not contained by the base URI '{baseUriPrefix}'.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void EnsureBaseUriPopulated()
|
||||||
|
{
|
||||||
|
// The <base href> is fixed for the lifetime of the page, so just cache it
|
||||||
|
if (_baseUriString == null)
|
||||||
|
{
|
||||||
|
var baseUri = RegisteredFunction.InvokeUnmarshalled<string>(
|
||||||
|
$"{_functionPrefix}.getBaseURI");
|
||||||
|
_baseUriString = ToBaseUriPrefix(baseUri);
|
||||||
|
_baseUri = new Uri(_baseUriString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void NotifyLocationChanged(string newAbsoluteUri)
|
private static void NotifyLocationChanged(string newAbsoluteUri)
|
||||||
{
|
{
|
||||||
_currentAbsoluteUri = newAbsoluteUri;
|
_currentAbsoluteUri = newAbsoluteUri;
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using Microsoft.AspNetCore.Blazor.Services;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
|
|
@ -39,7 +40,7 @@ namespace Microsoft.AspNetCore.Blazor.Browser.Services
|
||||||
|
|
||||||
private void AddDefaultServices(ServiceCollection serviceCollection)
|
private void AddDefaultServices(ServiceCollection serviceCollection)
|
||||||
{
|
{
|
||||||
// TODO: Add default services for HttpClient, IUrlHelper, etc.
|
serviceCollection.AddSingleton<IUriHelper>(new BrowserUriHelper());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Blazor.Services
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Helpers for working with URIs and navigation state.
|
||||||
|
/// </summary>
|
||||||
|
public interface IUriHelper
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current absolute URI.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The browser's current absolute URI.</returns>
|
||||||
|
string GetAbsoluteUri();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An event that fires when the navigation location has changed.
|
||||||
|
/// </summary>
|
||||||
|
event EventHandler<string> OnLocationChanged;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts a relative URI into an absolute one (by resolving it
|
||||||
|
/// relative to the current absolute URI).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="relativeUri">The relative URI.</param>
|
||||||
|
/// <returns>The absolute URI.</returns>
|
||||||
|
Uri ToAbsoluteUri(string href);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the URI prefix that can be prepended before URI paths to produce an absolute URI.
|
||||||
|
/// Typically this corresponds to the 'href' attribute on the document's <base> element.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The URI prefix.</returns>
|
||||||
|
string GetBaseUriPrefix();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Given a base URI prefix (e.g., one previously returned by <see cref="GetBaseUriPrefix"/>),
|
||||||
|
/// converts an absolute URI into one relative to the base URI prefix.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="baseUriPrefix">The base URI prefix (e.g., previously returned by <see cref="GetBaseUriPrefix"/>).</param>
|
||||||
|
/// <param name="absoluteUri">An absolute URI that is within the space of the base URI prefix.</param>
|
||||||
|
/// <returns>A relative URI path.</returns>
|
||||||
|
string ToBaseRelativePath(string baseUriPrefix, string locationAbsolute);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,14 +1,16 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using Microsoft.AspNetCore.Blazor.Browser.Routing;
|
using Microsoft.AspNetCore.Blazor.Browser.Services;
|
||||||
using System;
|
using System;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Blazor.Browser.Test
|
namespace Microsoft.AspNetCore.Blazor.Browser.Test
|
||||||
{
|
{
|
||||||
public class UriHelperTest
|
public class BrowserUriHelperTest
|
||||||
{
|
{
|
||||||
|
private BrowserUriHelper _browserUriHelper = new BrowserUriHelper();
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData("scheme://host/", "scheme://host")]
|
[InlineData("scheme://host/", "scheme://host")]
|
||||||
[InlineData("scheme://host:123/", "scheme://host:123")]
|
[InlineData("scheme://host:123/", "scheme://host:123")]
|
||||||
|
|
@ -17,7 +19,7 @@ namespace Microsoft.AspNetCore.Blazor.Browser.Test
|
||||||
[InlineData("scheme://host/path/page?query=string&another=here", "scheme://host/path")]
|
[InlineData("scheme://host/path/page?query=string&another=here", "scheme://host/path")]
|
||||||
public void ComputesCorrectBaseUriPrefix(string baseUri, string expectedResult)
|
public void ComputesCorrectBaseUriPrefix(string baseUri, string expectedResult)
|
||||||
{
|
{
|
||||||
var actualResult = UriHelper.ToBaseUriPrefix(baseUri);
|
var actualResult = BrowserUriHelper.ToBaseUriPrefix(baseUri);
|
||||||
Assert.Equal(expectedResult, actualResult);
|
Assert.Equal(expectedResult, actualResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -29,7 +31,7 @@ namespace Microsoft.AspNetCore.Blazor.Browser.Test
|
||||||
[InlineData("scheme://host/path", "scheme://host/path", "/")]
|
[InlineData("scheme://host/path", "scheme://host/path", "/")]
|
||||||
public void ComputesCorrectValidBaseRelativePaths(string baseUriPrefix, string absoluteUri, string expectedResult)
|
public void ComputesCorrectValidBaseRelativePaths(string baseUriPrefix, string absoluteUri, string expectedResult)
|
||||||
{
|
{
|
||||||
var actualResult = UriHelper.ToBaseRelativePath(baseUriPrefix, absoluteUri);
|
var actualResult = _browserUriHelper.ToBaseRelativePath(baseUriPrefix, absoluteUri);
|
||||||
Assert.Equal(expectedResult, actualResult);
|
Assert.Equal(expectedResult, actualResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -40,7 +42,7 @@ namespace Microsoft.AspNetCore.Blazor.Browser.Test
|
||||||
{
|
{
|
||||||
var ex = Assert.Throws<ArgumentException>(() =>
|
var ex = Assert.Throws<ArgumentException>(() =>
|
||||||
{
|
{
|
||||||
UriHelper.ToBaseRelativePath(baseUriPrefix, absoluteUri);
|
_browserUriHelper.ToBaseRelativePath(baseUriPrefix, absoluteUri);
|
||||||
});
|
});
|
||||||
|
|
||||||
Assert.Equal(
|
Assert.Equal(
|
||||||
Loading…
Reference in New Issue