| File: HotReloadService.cs | Web Access |
| Project: src\aspnetcore\src\Mvc\Mvc\src\Microsoft.AspNetCore.Mvc.csproj (Microsoft.AspNetCore.Mvc) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Reflection.Metadata; using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.AspNetCore.Mvc.Infrastructure; using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata; using Microsoft.AspNetCore.Mvc.Razor; using Microsoft.Extensions.Primitives; [assembly: MetadataUpdateHandler(typeof(Microsoft.AspNetCore.Mvc.HotReload.HotReloadService))] namespace Microsoft.AspNetCore.Mvc.HotReload; internal sealed class HotReloadService : IActionDescriptorChangeProvider, IDisposable { private readonly DefaultModelMetadataProvider? _modelMetadataProvider; private readonly DefaultControllerPropertyActivator? _controllerPropertyActivator; private readonly RazorHotReload? _razorHotReload; private CancellationTokenSource _tokenSource = new(); public HotReloadService( IModelMetadataProvider modelMetadataProvider, IControllerPropertyActivator controllerPropertyActivator) : this(modelMetadataProvider, controllerPropertyActivator, null) { } public HotReloadService( IModelMetadataProvider modelMetadataProvider, IControllerPropertyActivator controllerPropertyActivator, RazorHotReload? razorHotReload) { ClearCacheEvent += NotifyClearCache; UpdateApplicationEvent += NotifyUpdateApplication; if (modelMetadataProvider.GetType() == typeof(DefaultModelMetadataProvider)) { _modelMetadataProvider = (DefaultModelMetadataProvider)modelMetadataProvider; } if (controllerPropertyActivator is DefaultControllerPropertyActivator defaultControllerPropertyActivator) { _controllerPropertyActivator = defaultControllerPropertyActivator; } _razorHotReload = razorHotReload; } private static event Action<Type[]?>? ClearCacheEvent; private static event Action<Type[]?>? UpdateApplicationEvent; public static void ClearCache(Type[]? changedTypes) { ClearCacheEvent?.Invoke(changedTypes); } public static void UpdateApplication(Type[]? changedTypes) { UpdateApplicationEvent?.Invoke(changedTypes); } IChangeToken IActionDescriptorChangeProvider.GetChangeToken() => new CancellationChangeToken(_tokenSource.Token); private void NotifyClearCache(Type[]? changedTypes) { // Clear individual caches _modelMetadataProvider?.ClearCache(); _controllerPropertyActivator?.ClearCache(); _razorHotReload?.ClearCache(changedTypes); } private void NotifyUpdateApplication(Type[]? changedTypes) { // Trigger the ActionDescriptorChangeProvider var current = Interlocked.Exchange(ref _tokenSource, new CancellationTokenSource()); current.Cancel(); } public void Dispose() { ClearCacheEvent -= NotifyClearCache; UpdateApplicationEvent -= NotifyUpdateApplication; } }