-
Notifications
You must be signed in to change notification settings - Fork 927
/
Copy pathReactBuilderExtensions.cs
109 lines (97 loc) · 3.79 KB
/
ReactBuilderExtensions.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/*
* Copyright (c) 2015, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using React.Exceptions;
using React.TinyIoC;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json.Serialization;
#if !NET451
using Microsoft.Extensions.Caching.Memory;
#endif
namespace React.AspNet
{
/// <summary>
/// Handles registering ReactJS.NET middleware in an ASP.NET <see cref="IApplicationBuilder"/>.
/// </summary>
public static class ReactBuilderExtensions
{
/// <summary>
/// Initialises ReactJS.NET for this application
/// </summary>
/// <param name="app">ASP.NET application builder</param>
/// <param name="configure">ReactJS.NET configuration</param>
/// <param name="fileOptions">Options to use for serving files</param>
/// <returns>The application builder (for chaining)</returns>
public static IApplicationBuilder UseReact(
this IApplicationBuilder app,
Action<IReactSiteConfiguration> configure,
BabelFileOptions fileOptions = null
)
{
EnsureServicesRegistered(app);
RegisterAspNetServices(React.AssemblyRegistration.Container, app.ApplicationServices);
Initializer.Initialize(registerOptions => AsPerRequestSingleton(
app.ApplicationServices.GetService<IHttpContextAccessor>(),
registerOptions
));
// Camelcase JSON properties by default - Can be overridden per-site in "configure".
ReactSiteConfiguration.Configuration.JsonSerializerSettings.ContractResolver =
new CamelCasePropertyNamesContractResolver();
configure(ReactSiteConfiguration.Configuration);
// Allow serving of .jsx files
app.UseMiddleware<BabelFileMiddleware>(fileOptions ?? new BabelFileOptions());
return app;
}
/// <summary>
/// Registers a class such that every ASP.NET web request has a single instance of it.
/// </summary>
/// <param name="httpContextAccessor">ASP.NET HTTP context accessor</param>
/// <param name="registerOptions">Registration options</param>
/// <returns>Registration options (for chaining)</returns>
private static TinyIoCContainer.RegisterOptions AsPerRequestSingleton(
IHttpContextAccessor httpContextAccessor,
TinyIoCContainer.RegisterOptions registerOptions
)
{
return TinyIoCContainer.RegisterOptions.ToCustomLifetimeManager(
registerOptions,
new HttpContextLifetimeProvider(httpContextAccessor),
"per request singleton"
);
}
/// <summary>
/// Ensures React services have been registered in the ASP.NET dependency injection container.
/// </summary>
/// <param name="app">ASP.NET application builder</param>
private static void EnsureServicesRegistered(IApplicationBuilder app)
{
var registrations = app.ApplicationServices.GetService<HttpContextLifetimeProvider.PerRequestRegistrations>();
if (registrations == null)
{
throw new ReactNotInitialisedException("Please call services.AddReact() before app.UseReact().");
}
}
/// <summary>
/// Registers required ASP.NET services in ReactJS.NET's TinyIoC container. This is used
/// for ASP.NET services that are required by ReactJS.NET.
/// </summary>
/// <param name="container">ReactJS.NET dependency injection container</param>
/// <param name="services">ASP.NET dependency injection container</param>
private static void RegisterAspNetServices(TinyIoCContainer container, IServiceProvider services)
{
container.Register(services.GetRequiredService<IHostingEnvironment>());
#if !NET451
container.Register(services.GetRequiredService<IMemoryCache>());
#endif
}
}
}