예제 #1
0
    public static async Task ReceiveDeltas(HotReloadAgent hotReloadAgent)
    {
        Log("Attempting to receive deltas.");

        // This value is configured by dotnet-watch when the app is to be launched.
        var namedPipeName = Environment.GetEnvironmentVariable("DOTNET_HOTRELOAD_NAMEDPIPE_NAME") ??
                            throw new InvalidOperationException("DOTNET_HOTRELOAD_NAMEDPIPE_NAME was not specified.");

        using var pipeClient = new NamedPipeClientStream(".", namedPipeName, PipeDirection.InOut, PipeOptions.CurrentUserOnly | PipeOptions.Asynchronous);
        try
        {
            await pipeClient.ConnectAsync(5000);

            Log("Connected.");
        }
        catch (TimeoutException)
        {
            Log("Unable to connect to hot-reload server.");
            return;
        }

        while (pipeClient.IsConnected)
        {
            var update = await UpdatePayload.ReadAsync(pipeClient, default);

            Log("Attempting to apply deltas.");

            hotReloadAgent.ApplyDeltas(update.Deltas);
            pipeClient.WriteByte((byte)ApplyResult.Success);
        }
        Log("Stopped received delta updates. Server is no longer connected.");
    }
예제 #2
0
    public static async Task ReceiveDeltas()
    {
        Log("Attempting to receive deltas.");

        using var pipeClient = new NamedPipeClientStream(".", "netcore-hot-reload", PipeDirection.InOut, PipeOptions.CurrentUserOnly | PipeOptions.Asynchronous);
        try
        {
            await pipeClient.ConnectAsync(5000);

            Log("Connected.");
        }
        catch (TimeoutException)
        {
            Log("Unable to connect to hot-reload server.");
            return;
        }

        List <Action>?receiveDeltaNotifications = null;

        while (pipeClient.IsConnected)
        {
            var update = await UpdatePayload.ReadAsync(pipeClient, default);

            Log("Attempting to apply deltas.");

            try
            {
                foreach (var item in update.Deltas)
                {
                    var assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.Modules.FirstOrDefault() is Module m && m.ModuleVersionId == item.ModuleId);
                    if (assembly is not null)
                    {
                        System.Reflection.Metadata.AssemblyExtensions.ApplyUpdate(assembly, item.MetadataDelta, item.ILDelta, ReadOnlySpan <byte> .Empty);
                    }
                }

                // We want to base this off of mvids, but we'll figure that out eventually.
                var applyResult = update.ChangedFile is string changedFile && changedFile.EndsWith(".razor", StringComparison.Ordinal) ?
                                  ApplyResult.Success :
                                  ApplyResult.Success_RefreshBrowser;
                pipeClient.WriteByte((byte)applyResult);

                // Defer discovering the receiving deltas until the first hot reload delta.
                // This should give enough opportunity for AppDomain.GetAssemblies() to be sufficiently populated.
                receiveDeltaNotifications ??= GetAssembliesReceivingDeltas();
                receiveDeltaNotifications.ForEach(r => r.Invoke());

                Log("Deltas applied.");
            }
            catch (Exception ex)
            {
                Log(ex.ToString());
            }
        }
        Log("Stopped received delta updates. Server is no longer connected.");
    }