Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove IReceiveHotReloadContext and HotReloadContext #31281

Merged
5 commits merged into from
Mar 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 2 additions & 9 deletions src/Components/Components/src/ComponentBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.HotReload;
using Microsoft.AspNetCore.Components.Rendering;

namespace Microsoft.AspNetCore.Components
Expand All @@ -22,15 +21,14 @@ namespace Microsoft.AspNetCore.Components
/// Optional base class for components. Alternatively, components may
/// implement <see cref="IComponent"/> directly.
/// </summary>
public abstract class ComponentBase : IComponent, IHandleEvent, IHandleAfterRender, IReceiveHotReloadContext
public abstract class ComponentBase : IComponent, IHandleEvent, IHandleAfterRender
{
private readonly RenderFragment _renderFragment;
private RenderHandle _renderHandle;
private bool _initialized;
private bool _hasNeverRendered = true;
private bool _hasPendingQueuedRender;
private bool _hasCalledOnAfterRender;
private HotReloadContext? _hotReloadContext;

/// <summary>
/// Constructs an instance of <see cref="ComponentBase"/>.
Expand Down Expand Up @@ -104,7 +102,7 @@ protected void StateHasChanged()
return;
}

if (_hasNeverRendered || ShouldRender() || (_hotReloadContext?.IsHotReloading ?? false))
if (_hasNeverRendered || ShouldRender() || _renderHandle.IsHotReloading)
{
_hasPendingQueuedRender = true;

Expand Down Expand Up @@ -331,10 +329,5 @@ Task IHandleAfterRender.OnAfterRenderAsync()
// have to use "async void" and do their own exception handling in
// the case where they want to start an async task.
}

void IReceiveHotReloadContext.Receive(HotReloadContext context)
{
_hotReloadContext = context;
}
}
}
16 changes: 0 additions & 16 deletions src/Components/Components/src/HotReload/HotReloadContext.cs

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,16 @@
<assembly fullname="Microsoft.AspNetCore.Components" >
<!-- HotReload will not be available in a trimmed app. We'll attempt to aggressively remove all references to it. -->
<type fullname="Microsoft.AspNetCore.Components.RenderTree.Renderer">
<!-- Renderer.IsHotReloading will always return false in a trimmed app. -->
<method signature="System.Boolean get_IsHotReloading()" body="stub" value="false" />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it also possible to short-circuit RenderHandle.IsHotReloading to be always-false so that, in production, we can skip both the null check and the property getter call that it does on each call to SetParametersAsync?

I know this is small beans but it would be super nice to have zero overhead for this feature in production.

<method signature="System.Void RenderRootComponentsOnHotReload()" body="remove" />
<method signature="System.Void InitializeHotReload(System.IServiceProvider)" body="stub" />
<method signature="System.Void InstatiateComponentForHotReload(Microsoft.AspNetCore.Components.IComponent)" body="stub" />
<method signature="System.Void CaptureRootComponentForHotReload(Microsoft.AspNetCore.Components.ParameterView,Microsoft.AspNetCore.Components.Rendering.ComponentState)" body="stub" />
<method signature="System.Void DisposeForHotReload()" body="stub" />
</type>
pranavkm marked this conversation as resolved.
Show resolved Hide resolved
<type fullname="Microsoft.AspNetCore.Components.HotReload.HotReloadContext">
<method signature="System.Boolean get_IsHotReloading()" body="stub" value="false" />
<method signature="System.Void set_IsHotReloading(System.Boolean)" body="remove" />
</type>
<type fullname="Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder">
<method signature="System.Boolean IsHotReloading(Microsoft.AspNetCore.Components.RenderTree.Renderer)" body="stub" value="false" />
<!-- Avoid any overhead in RenderHandle.IsHotReloading by aggressively trimming it -->
<type fullname="Microsoft.AspNetCore.Components.RenderHandle">
<method signature="System.Boolean get_IsHotReloading()" body="stub" value="false" />
</type>
</assembly>
</linker>
6 changes: 1 addition & 5 deletions src/Components/Components/src/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,6 @@ Microsoft.AspNetCore.Components.ComponentApplicationState.PersistAsJson<TValue>(
Microsoft.AspNetCore.Components.ComponentApplicationState.PersistState(string! key, byte[]! value) -> void
Microsoft.AspNetCore.Components.ComponentApplicationState.TryTakeAsJson<TValue>(string! key, out TValue? instance) -> bool
Microsoft.AspNetCore.Components.ComponentApplicationState.TryTakePersistedState(string! key, out byte[]? value) -> bool
Microsoft.AspNetCore.Components.HotReload.HotReloadContext
Microsoft.AspNetCore.Components.HotReload.HotReloadContext.HotReloadContext() -> void
Microsoft.AspNetCore.Components.HotReload.HotReloadContext.IsHotReloading.get -> bool
Microsoft.AspNetCore.Components.HotReload.IReceiveHotReloadContext
Microsoft.AspNetCore.Components.HotReload.IReceiveHotReloadContext.Receive(Microsoft.AspNetCore.Components.HotReload.HotReloadContext! context) -> void
Microsoft.AspNetCore.Components.Lifetime.ComponentApplicationLifetime
Microsoft.AspNetCore.Components.Lifetime.ComponentApplicationLifetime.ComponentApplicationLifetime(Microsoft.Extensions.Logging.ILogger<Microsoft.AspNetCore.Components.Lifetime.ComponentApplicationLifetime!>! logger) -> void
Microsoft.AspNetCore.Components.Lifetime.ComponentApplicationLifetime.PersistStateAsync(Microsoft.AspNetCore.Components.Lifetime.IComponentApplicationStateStore! store, Microsoft.AspNetCore.Components.RenderTree.Renderer! renderer) -> System.Threading.Tasks.Task!
Expand All @@ -21,6 +16,7 @@ Microsoft.AspNetCore.Components.Lifetime.ComponentApplicationLifetime.State.get
Microsoft.AspNetCore.Components.Lifetime.IComponentApplicationStateStore
Microsoft.AspNetCore.Components.Lifetime.IComponentApplicationStateStore.GetPersistedStateAsync() -> System.Threading.Tasks.Task<System.Collections.Generic.IDictionary<string!, byte[]!>!>!
Microsoft.AspNetCore.Components.Lifetime.IComponentApplicationStateStore.PersistStateAsync(System.Collections.Generic.IReadOnlyDictionary<string!, byte[]!>! state) -> System.Threading.Tasks.Task!
Microsoft.AspNetCore.Components.RenderHandle.IsHotReloading.get -> bool
Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder.Dispose() -> void
Microsoft.AspNetCore.Components.Routing.Router.PreferExactMatches.get -> bool
Microsoft.AspNetCore.Components.Routing.Router.PreferExactMatches.set -> void
Expand Down
12 changes: 8 additions & 4 deletions src/Components/Components/src/RenderHandle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace Microsoft.AspNetCore.Components
/// </summary>
public readonly struct RenderHandle
{
private readonly Renderer _renderer;
private readonly Renderer? _renderer;
private readonly int _componentId;

internal RenderHandle(Renderer renderer, int componentId)
Expand All @@ -22,7 +22,7 @@ internal RenderHandle(Renderer renderer, int componentId)
}

/// <summary>
/// Gets the <see cref="Microsoft.AspNetCore.Components.Dispatcher" /> associated with the component.
/// Gets the <see cref="Components.Dispatcher" /> associated with the component.
/// </summary>
public Dispatcher Dispatcher
{
Expand All @@ -41,8 +41,12 @@ public Dispatcher Dispatcher
/// Gets a value that indicates whether the <see cref="RenderHandle"/> has been
/// initialized and is ready to use.
/// </summary>
public bool IsInitialized
=> _renderer != null;
public bool IsInitialized => _renderer is not null;

/// <summary>
/// Gets a value that determines if the <see cref="Renderer"/> is triggering a render in response to a hot-reload change.
/// </summary>
public bool IsHotReloading => _renderer?.IsHotReloading ?? false;

/// <summary>
/// Notifies the renderer that the component should be rendered.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -541,17 +541,12 @@ private static void UpdateRetainedChildComponent(
var oldParameters = new ParameterView(ParameterViewLifetime.Unbound, oldTree, oldComponentIndex);
var newParametersLifetime = new ParameterViewLifetime(diffContext.BatchBuilder);
var newParameters = new ParameterView(newParametersLifetime, newTree, newComponentIndex);
if (!newParameters.DefinitelyEquals(oldParameters) || IsHotReloading(diffContext.Renderer))
if (!newParameters.DefinitelyEquals(oldParameters) || diffContext.Renderer.IsHotReloading)
{
componentState.SetDirectParameters(newParameters);
}
}

/// <remarks>
/// Intentionally authored as a separate method so we can trim this code.
/// </remarks>
private static bool IsHotReloading(Renderer renderer) => renderer.HotReloadContext.IsHotReloading;

private static int NextSiblingIndex(in RenderTreeFrame frame, int frameIndex)
{
switch (frame.FrameTypeField)
Expand Down
27 changes: 7 additions & 20 deletions src/Components/Components/src/RenderTree/Renderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ public abstract partial class Renderer : IDisposable, IAsyncDisposable
private readonly Dictionary<ulong, ulong> _eventHandlerIdReplacements = new Dictionary<ulong, ulong>();
private readonly ILogger<Renderer> _logger;
private readonly ComponentFactory _componentFactory;
private HotReloadContext _hotReloadContext;
private HotReloadEnvironment? _hotReloadEnvironment;
private List<(ComponentState, ParameterView)>? _rootComponents;

Expand Down Expand Up @@ -102,8 +101,6 @@ public Renderer(IServiceProvider serviceProvider, ILoggerFactory loggerFactory,

private void InitializeHotReload(IServiceProvider serviceProvider)
{
_hotReloadContext = new();

// HotReloadEnvironment is a test-specific feature and may not be available in a running app. We'll fallback to the default instance
// if the test fixture does not provide one.
_hotReloadEnvironment = serviceProvider.GetService<HotReloadEnvironment>() ?? HotReloadEnvironment.Instance;
Expand Down Expand Up @@ -131,7 +128,10 @@ private static IComponentActivator GetComponentActivatorOrDefault(IServiceProvid
/// </summary>
protected internal ElementReferenceContext? ElementReferenceContext { get; protected set; }

internal HotReloadContext HotReloadContext => _hotReloadContext;
/// <summary>
/// Gets a value that determines if the <see cref="Renderer"/> is triggering a render in response to a hot-reload change.
/// </summary>
internal bool IsHotReloading { get; private set; }

private async void RenderRootComponentsOnHotReload()
{
Expand All @@ -142,7 +142,7 @@ await Dispatcher.InvokeAsync(() =>
return;
}

HotReloadContext.IsHotReloading = true;
IsHotReloading = true;
try
{
foreach (var (componentState, initialParameters) in _rootComponents)
Expand All @@ -152,7 +152,7 @@ await Dispatcher.InvokeAsync(() =>
}
finally
{
HotReloadContext.IsHotReloading = false;
IsHotReloading = false;
}
});
}
Expand All @@ -164,20 +164,7 @@ await Dispatcher.InvokeAsync(() =>
/// <returns>The component instance.</returns>
protected IComponent InstantiateComponent([DynamicallyAccessedMembers(Component)] Type componentType)
{
var component = _componentFactory.InstantiateComponent(_serviceProvider, componentType);
InstatiateComponentForHotReload(component);
return component;
}

/// <remarks>
/// Intentionally authored as a separate method call so we can trim this code.
/// </remarks>
private void InstatiateComponentForHotReload(IComponent component)
{
if (_hotReloadEnvironment is not null && _hotReloadEnvironment.IsHotReloadEnabled && component is IReceiveHotReloadContext receiveHotReloadContext)
{
receiveHotReloadContext.Receive(HotReloadContext);
}
return _componentFactory.InstantiateComponent(_serviceProvider, componentType);
}

/// <summary>
Expand Down