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);
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { registerFunction } from '../Interop/RegisteredFunction';
|
||||
import { platform } from '../Environment';
|
||||
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 hasRegisteredEventListeners = false;
|
||||
|
||||
|
|
@ -37,8 +37,8 @@ function handleInternalNavigation() {
|
|||
if (!notifyLocationChangedMethod) {
|
||||
notifyLocationChangedMethod = platform.findMethod(
|
||||
'Microsoft.AspNetCore.Blazor.Browser',
|
||||
'Microsoft.AspNetCore.Blazor.Browser.Routing',
|
||||
'UriHelper',
|
||||
'Microsoft.AspNetCore.Blazor.Browser.Services',
|
||||
'BrowserUriHelper',
|
||||
'NotifyLocationChanged'
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ using System.Reflection;
|
|||
using Microsoft.AspNetCore.Blazor.Components;
|
||||
using Microsoft.AspNetCore.Blazor.Layouts;
|
||||
using Microsoft.AspNetCore.Blazor.RenderTree;
|
||||
using Microsoft.AspNetCore.Blazor.Services;
|
||||
|
||||
namespace Microsoft.AspNetCore.Blazor.Browser.Routing
|
||||
{
|
||||
|
|
@ -22,6 +23,8 @@ namespace Microsoft.AspNetCore.Blazor.Browser.Routing
|
|||
string _baseUriPrefix;
|
||||
string _locationAbsolute;
|
||||
|
||||
[Inject] private IUriHelper UriHelper { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the assembly that should be searched, along with its referenced
|
||||
/// assemblies, for components matching the URI.
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
using Microsoft.AspNetCore.Blazor.Components;
|
||||
using Microsoft.AspNetCore.Blazor.RenderTree;
|
||||
using Microsoft.AspNetCore.Blazor.Services;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
|
@ -32,6 +33,8 @@ namespace Microsoft.AspNetCore.Blazor.Browser.Routing
|
|||
private string _hrefAbsolute;
|
||||
private IReadOnlyDictionary<string, object> _allAttributes;
|
||||
|
||||
[Inject] private IUriHelper UriHelper { get; set; }
|
||||
|
||||
public void Init(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.
|
||||
|
||||
using Microsoft.AspNetCore.Blazor.Browser.Interop;
|
||||
using Microsoft.AspNetCore.Blazor.Services;
|
||||
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>
|
||||
/// Helpers for working with URIs and navigation state.
|
||||
/// Default browser implementation of <see cref="IUriHelper"/>.
|
||||
/// </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 EventHandler<string> _onLocationChanged;
|
||||
static string _baseUriString;
|
||||
static Uri _baseUri;
|
||||
static EventHandler<string> _onLocationChanged;
|
||||
static bool _hasEnabledNavigationInterception;
|
||||
|
||||
/// <summary>
|
||||
/// An event that fires when the navigation location has changed.
|
||||
/// </summary>
|
||||
public static event EventHandler<string> OnLocationChanged
|
||||
/// <inheritdoc />
|
||||
public event EventHandler<string> OnLocationChanged
|
||||
{
|
||||
add
|
||||
{
|
||||
|
|
@ -38,63 +41,34 @@ namespace Microsoft.AspNetCore.Blazor.Browser.Routing
|
|||
}
|
||||
}
|
||||
|
||||
/// <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>
|
||||
public static string GetBaseUriPrefix()
|
||||
/// <inheritdoc />
|
||||
public string GetBaseUriPrefix()
|
||||
{
|
||||
EnsureBaseUriPopulated();
|
||||
return _baseUriString;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the browser's current absolute URI.
|
||||
/// </summary>
|
||||
/// <returns>The browser's current absolute URI.</returns>
|
||||
public static string GetAbsoluteUri()
|
||||
/// <inheritdoc />
|
||||
public string GetAbsoluteUri()
|
||||
{
|
||||
if (_currentAbsoluteUri == null)
|
||||
{
|
||||
_currentAbsoluteUri = RegisteredFunction.InvokeUnmarshalled<string>(
|
||||
$"{_functionPrefix}.getLocationHref");
|
||||
$"{_functionPrefix}.getLocationHref");
|
||||
}
|
||||
|
||||
return _currentAbsoluteUri;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a relative URI into an absolute one.
|
||||
/// </summary>
|
||||
/// <param name="relativeUri">The relative URI.</param>
|
||||
/// <returns>The absolute URI.</returns>
|
||||
public static Uri ToAbsoluteUri(string relativeUri)
|
||||
/// <inheritdoc />
|
||||
public Uri ToAbsoluteUri(string relativeUri)
|
||||
{
|
||||
EnsureBaseUriPopulated();
|
||||
return new Uri(_baseUri, relativeUri);
|
||||
}
|
||||
|
||||
/// <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>
|
||||
public static string ToBaseRelativePath(string baseUriPrefix, string absoluteUri)
|
||||
/// <inheritdoc />
|
||||
public string ToBaseRelativePath(string baseUriPrefix, string absoluteUri)
|
||||
{
|
||||
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}'.");
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
_currentAbsoluteUri = newAbsoluteUri;
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
// 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 Microsoft.AspNetCore.Blazor.Services;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
|
||||
|
|
@ -39,7 +40,7 @@ namespace Microsoft.AspNetCore.Blazor.Browser.Services
|
|||
|
||||
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.
|
||||
// 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 Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Blazor.Browser.Test
|
||||
{
|
||||
public class UriHelperTest
|
||||
public class BrowserUriHelperTest
|
||||
{
|
||||
private BrowserUriHelper _browserUriHelper = new BrowserUriHelper();
|
||||
|
||||
[Theory]
|
||||
[InlineData("scheme://host/", "scheme://host")]
|
||||
[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")]
|
||||
public void ComputesCorrectBaseUriPrefix(string baseUri, string expectedResult)
|
||||
{
|
||||
var actualResult = UriHelper.ToBaseUriPrefix(baseUri);
|
||||
var actualResult = BrowserUriHelper.ToBaseUriPrefix(baseUri);
|
||||
Assert.Equal(expectedResult, actualResult);
|
||||
}
|
||||
|
||||
|
|
@ -29,7 +31,7 @@ namespace Microsoft.AspNetCore.Blazor.Browser.Test
|
|||
[InlineData("scheme://host/path", "scheme://host/path", "/")]
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -40,7 +42,7 @@ namespace Microsoft.AspNetCore.Blazor.Browser.Test
|
|||
{
|
||||
var ex = Assert.Throws<ArgumentException>(() =>
|
||||
{
|
||||
UriHelper.ToBaseRelativePath(baseUriPrefix, absoluteUri);
|
||||
_browserUriHelper.ToBaseRelativePath(baseUriPrefix, absoluteUri);
|
||||
});
|
||||
|
||||
Assert.Equal(
|
||||
Loading…
Reference in New Issue