Remove System.Runtime.Loader dependency to enable net461 support. Use IApplicationLifetime instead of AssemblyLoadContext.Default.Unloading.

This commit is contained in:
Steve Sanderson
2017-06-07 11:45:14 +01:00
parent 2aaceaa9f8
commit b444831c8d
9 changed files with 50 additions and 24 deletions

View File

@@ -1,5 +1,6 @@
using System;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http.Features;
@@ -24,6 +25,7 @@ namespace Microsoft.AspNetCore.SpaServices.Prerendering
private static INodeServices _fallbackNodeServices; // Used only if no INodeServices was registered with DI
private readonly string _applicationBasePath;
private readonly CancellationToken _applicationStoppingToken;
private readonly INodeServices _nodeServices;
/// <summary>
@@ -35,6 +37,9 @@ namespace Microsoft.AspNetCore.SpaServices.Prerendering
var hostEnv = (IHostingEnvironment) serviceProvider.GetService(typeof(IHostingEnvironment));
_nodeServices = (INodeServices) serviceProvider.GetService(typeof(INodeServices)) ?? _fallbackNodeServices;
_applicationBasePath = hostEnv.ContentRootPath;
var applicationLifetime = (IApplicationLifetime) serviceProvider.GetService(typeof(IApplicationLifetime));
_applicationStoppingToken = applicationLifetime.ApplicationStopping;
// Consider removing the following. Having it means you can get away with not putting app.AddNodeServices()
// in your startup file, but then again it might be confusing that you don't need to.
@@ -101,6 +106,7 @@ namespace Microsoft.AspNetCore.SpaServices.Prerendering
var result = await Prerenderer.RenderToString(
_applicationBasePath,
_nodeServices,
_applicationStoppingToken,
new JavaScriptModuleExport(ModuleName)
{
ExportName = ExportName

View File

@@ -1,4 +1,5 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.NodeServices;
@@ -9,22 +10,16 @@ namespace Microsoft.AspNetCore.SpaServices.Prerendering
/// </summary>
public static class Prerenderer
{
private static readonly Lazy<StringAsTempFile> NodeScript;
private static readonly object CreateNodeScriptLock = new object();
static Prerenderer()
{
NodeScript = new Lazy<StringAsTempFile>(() =>
{
var script = EmbeddedResourceReader.Read(typeof(Prerenderer), "/Content/Node/prerenderer.js");
return new StringAsTempFile(script); // Will be cleaned up on process exit
});
}
private static StringAsTempFile NodeScript;
/// <summary>
/// Performs server-side prerendering by invoking code in Node.js.
/// </summary>
/// <param name="applicationBasePath">The root path to your application. This is used when resolving project-relative paths.</param>
/// <param name="nodeServices">The instance of <see cref="INodeServices"/> that will be used to invoke JavaScript code.</param>
/// <param name="applicationStoppingToken">A token that indicates when the host application is stopping.</param>
/// <param name="bootModule">The path to the JavaScript file containing the prerendering logic.</param>
/// <param name="requestAbsoluteUrl">The URL of the currently-executing HTTP request. This is supplied to the prerendering code.</param>
/// <param name="requestPathAndQuery">The path and query part of the URL of the currently-executing HTTP request. This is supplied to the prerendering code.</param>
@@ -35,6 +30,7 @@ namespace Microsoft.AspNetCore.SpaServices.Prerendering
public static Task<RenderToStringResult> RenderToString(
string applicationBasePath,
INodeServices nodeServices,
CancellationToken applicationStoppingToken,
JavaScriptModuleExport bootModule,
string requestAbsoluteUrl,
string requestPathAndQuery,
@@ -43,7 +39,7 @@ namespace Microsoft.AspNetCore.SpaServices.Prerendering
string requestPathBase)
{
return nodeServices.InvokeExportAsync<RenderToStringResult>(
NodeScript.Value.FileName,
GetNodeScriptFilename(applicationStoppingToken),
"renderToString",
applicationBasePath,
bootModule,
@@ -53,5 +49,19 @@ namespace Microsoft.AspNetCore.SpaServices.Prerendering
timeoutMilliseconds,
requestPathBase);
}
private static string GetNodeScriptFilename(CancellationToken applicationStoppingToken)
{
lock(CreateNodeScriptLock)
{
if (NodeScript == null)
{
var script = EmbeddedResourceReader.Read(typeof(Prerenderer), "/Content/Node/prerenderer.js");
NodeScript = new StringAsTempFile(script, applicationStoppingToken); // Will be cleaned up on process exit
}
}
return NodeScript.FileName;
}
}
}

View File

@@ -68,7 +68,7 @@ namespace Microsoft.AspNetCore.Builder
// Get a filename matching the middleware Node script
var script = EmbeddedResourceReader.Read(typeof(WebpackDevMiddleware),
"/Content/Node/webpack-dev-middleware.js");
var nodeScript = new StringAsTempFile(script); // Will be cleaned up on process exit
var nodeScript = new StringAsTempFile(script, nodeServicesOptions.ApplicationStoppingToken); // Will be cleaned up on process exit
// Ideally, this would be relative to the application's PathBase (so it could work in virtual directories)
// but it's not clear that such information exists during application startup, as opposed to within the context