Would it be safe to enable the use of the OnStart() method in My Extensions?

I'm hoping to move my new rewritten extensions to my main My Extensions script, but it requires using the OnStart() hook to set it up. It doesn't seem to be invoked when I test it within regular scripts, I would have to work around it and invoke it manually.

Any particular reason why the OnStart() hook isn't used in My Extensions? Could that be enabled?

I guess the hooks are only really used in the context of #loading them in. Any chance that could be revisited and allow #loading in My Extensions?

Comments

  • I'd second this request.

    My current workaround is to enable Always use a fresh process between executions and then I have this in my extensions

    public static class StaticConstructorsExtensions
    {
        [System.Runtime.CompilerServices.ModuleInitializer]
        internal static void ModuleInitializer()
        {
            // Code I always want to run goes here.
        }
    } 
    
  • clem0338
    edited July 6

    Thanks to @sgmoore, here is the trick I'm using for that

    in every script I want to catch a restart (or fresh start with little modification), I add

    #load "Helpers\OnRestartHelper"
    

    Then I add private static method "OnRestart" everywhere I want (script and/or extension, see screenshot)

    static void OnRestart() {
       // ....
    }
    

    And here is the content of "OnRestartHelper" (set as "C# Statements")

    ModuleInitializerClass.Signal();
    
    internal static class ModuleInitializerClass {
        private static bool IsFreshStart;
        [ModuleInitializer]
        internal static void ModuleInitializer() => IsFreshStart = true;
        internal static void Signal() {
            if (IsFreshStart) {
                IsFreshStart = false;
                return;
            }
    
            foreach (var onRestartMethod in Assembly.GetExecutingAssembly().Modules.SelectMany(m => m.GetTypes()).SelectMany(t => t.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)).Where(m => m.Name.Split("__").Last().Split("|").First() == "OnRestart"))
                onRestartMethod.Invoke(null, []);
        }
    }
    

  • @clem0338 - is there any reason you don't instead define an OnInit() hook method in Helpers\OnRestartHelper?

    https://www.linqpad.net/LinqReference.aspx

    OnInitDemo.linq:

    void Main()
    {   
    }
    
    void OnInit() => "Init".Dump();     // Executes once (like a module initializer)
    void OnStart() => "Start".Dump();   // Executes each time you run
    

    Test script:

    #load "OnInitDemo"
    
    "test".Dump();
    
  • @JoeAlbahari, simple, I'm stupid.

    not only, this is way clearer but also the system I was using does not even fix the initial request.

    Thanks for guiding me in the right direction