Skip to content

Add a notification mechanism for EnC and HotReload #49361

@StephaneDelcroix

Description

@StephaneDelcroix

Background and Motivation

One of the key work stream for the success of HotReload is a feedback mechanism so frameworks and 3rd party libraries knows that a type was hot reloaded and can decide to replace a live instance, invalidate a cache, refresh a binding, etc...

The proposed API isn't prescriptive, and other feedback mechanisms can be discussed, but it's quite important that the API is part of the BCL and the feature is supported by the runtime, so all frameworks will benefits from it, and it'll work in all HotReload scenarios (debugger and botnet watch).

This proposal was first mentioned in #45689, 2nd bullet of the 'Related API changes' section

Proposed API

namespace System.Reflection.Metadata
{
    [System.AttributeUsage(System.AttributeTargets.Assembly, AllowMultiple = true)]
    public sealed class  ApplyUpdateNotificationAttribute : Attribute
    {
        /// <summary>
        /// HotReload notification API
        ///
        /// Declares which static method to execute when a HotReload delta is applied. The hot reload agent is responsible
        /// for scanning assemblies at load, and register the notifiers.
        ///
        /// notifier signature should look like: internal static void BeforeUpdate(Type type) and/or AfterUpdate(Type type).
        /// </summary>
        /// <param name="type">The Type on which the notifier is defined</param>
        /// <exception cref="ArgumentNullException">type or notifier are null</exception>
        /// <exception cref="...">type or notifier does not exist, or notifier isn't static, or doesn't have the right signature</exception>
        public ApplyUpdateNotificationAttribute (Type type)   
    }
}

Usage Examples

This is how a UI Framework could reload a view when an HotReload change is applied

[assembly:ApplyUpdateNotification(typeof(HotReloadExtensions)]

namespace MyUIFramework
{
    public class View {
        public View Parent {get; set;} // setting the Parent sets the Child on the Parent view

        public View ()
        {
            HotReloadExtensions.RegisterInstance(this);
        }
    }

    internal static class HotReloadExtensions
    {
        // Keep weakRef of created views in a cache
        public static void RegisterInstance(View view) {...}

        // retrieve values from the cache
        static IEnumerable<View> GetViewsOfType(Type type) {...}

        // the notifier, declared by the attribute
        public static void AfterUpdate(Type type)
        {
            foreach (var oldinstance in GetViewsOfType(type)
            {
            }
        }
    }
}

Alternative Designs

  1. event: creating an event has the problem of registration, mainly for 3rd party libraries
  2. implement this capability at the framework level. repetitive work, and the runtime would still have to implement it's own mechanism to invalide its caches (I'm thinking ReflectionCache, ....)
  3. whatever applies the change could also trigger the notification, but that would require injecting some shared code in all platforms supporting EnC/HR

Risks

Unknown at this time

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions