From 9ec79ae9f76aada6014f1ee43fbd103175058d41 Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Mon, 11 Dec 2017 19:45:02 +0000 Subject: [PATCH] Start making standalone hosting work again by automatically locating the client app assembly --- samples/HostedInAspNet.Server/Startup.cs | 2 +- samples/MonoSanity/Startup.cs | 2 +- samples/MonoSanityClient/Examples.cs | 2 +- .../Server/Startup.cs | 34 ++++++++++++++++++- .../BlazorAppBuilderExtensions.cs | 9 ++--- 5 files changed, 41 insertions(+), 8 deletions(-) diff --git a/samples/HostedInAspNet.Server/Startup.cs b/samples/HostedInAspNet.Server/Startup.cs index 576c37f634..92ceba8905 100644 --- a/samples/HostedInAspNet.Server/Startup.cs +++ b/samples/HostedInAspNet.Server/Startup.cs @@ -25,7 +25,7 @@ namespace HostedInAspNet.Server app.UseBlazorDevelopmentServer("../HostedInAspNet.Client"); } - app.UseBlazor(); + app.UseBlazor(clientAssembly: typeof(Client.Program).Assembly); } } } diff --git a/samples/MonoSanity/Startup.cs b/samples/MonoSanity/Startup.cs index 144ea796f3..d40144e6fe 100644 --- a/samples/MonoSanity/Startup.cs +++ b/samples/MonoSanity/Startup.cs @@ -15,7 +15,7 @@ namespace MonoSanity { app.UseDeveloperExceptionPage(); app.UseFileServer(); - app.UseBlazor(); + app.UseBlazor(clientAssembly: typeof(MonoSanityClient.Examples).Assembly); } } } diff --git a/samples/MonoSanityClient/Examples.cs b/samples/MonoSanityClient/Examples.cs index 9983c89cd0..24be61d54e 100644 --- a/samples/MonoSanityClient/Examples.cs +++ b/samples/MonoSanityClient/Examples.cs @@ -6,7 +6,7 @@ using System.Text; namespace MonoSanityClient { - public class Examples + public static class Examples { public static string AddNumbers(int a, int b) => (a + b).ToString(); diff --git a/src/Microsoft.Blazor.DevHost/Server/Startup.cs b/src/Microsoft.Blazor.DevHost/Server/Startup.cs index 148aa8c7f6..94af9dca25 100644 --- a/src/Microsoft.Blazor.DevHost/Server/Startup.cs +++ b/src/Microsoft.Blazor.DevHost/Server/Startup.cs @@ -1,8 +1,12 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; +using System.Reflection; using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; +using System.IO; namespace Microsoft.Blazor.DevHost.Server { @@ -17,7 +21,35 @@ namespace Microsoft.Blazor.DevHost.Server { app.UseDeveloperExceptionPage(); app.UseBlazorDevelopmentServer("."); - app.UseBlazor(); // TODO + app.UseBlazor(clientAssembly: FindClientAssembly(app)); + } + + private static Assembly FindClientAssembly(IApplicationBuilder app) + { + var env = app.ApplicationServices.GetRequiredService(); + var contentRoot = env.ContentRootPath; + var binDir = FindClientBinDir(contentRoot); + var appName = Path.GetFileName(contentRoot); // TODO: Allow for the possibility that the assembly name has been overridden + var assemblyPath = Path.Combine(binDir, $"{appName}.dll"); + if (!File.Exists(assemblyPath)) + { + throw new FileNotFoundException($"Could not locate application assembly at expected location {assemblyPath}"); + } + + return Assembly.LoadFile(assemblyPath); + } + + private static string FindClientBinDir(string clientAppSourceRoot) + { + var binDebugDir = Path.Combine(clientAppSourceRoot, "bin", "Debug"); + var subdirectories = Directory.GetDirectories(binDebugDir); + if (subdirectories.Length != 1) + { + throw new InvalidOperationException($"Could not locate bin directory for Blazor app. " + + $"Expected to find exactly 1 subdirectory in '{binDebugDir}', but found {subdirectories.Length}."); + } + + return Path.Combine(binDebugDir, subdirectories[0]); } } } diff --git a/src/Microsoft.Blazor.Server/BlazorAppBuilderExtensions.cs b/src/Microsoft.Blazor.Server/BlazorAppBuilderExtensions.cs index 96dc2e743f..0d5c9af277 100644 --- a/src/Microsoft.Blazor.Server/BlazorAppBuilderExtensions.cs +++ b/src/Microsoft.Blazor.Server/BlazorAppBuilderExtensions.cs @@ -5,19 +5,20 @@ using Microsoft.AspNetCore.StaticFiles; using Microsoft.Blazor.Server.ClientFilesystem; using System.Collections.Generic; using System.Net.Mime; +using System.Reflection; namespace Microsoft.AspNetCore.Builder { public static class BlazorAppBuilderExtensions { - public static void UseBlazor(this IApplicationBuilder applicationBuilder) + public static void UseBlazor( + this IApplicationBuilder applicationBuilder, + Assembly clientAssembly) { - var clientAppAssembly = typeof(TProgram).Assembly; - applicationBuilder.UseStaticFiles(new StaticFileOptions { RequestPath = "/_framework", - FileProvider = ClientFileProvider.Instantiate(clientAppAssembly), + FileProvider = ClientFileProvider.Instantiate(clientAssembly), ContentTypeProvider = CreateContentTypeProvider(), }); }