1+ /*
2+ * Copyright (c) 2015, Facebook, Inc.
3+ * All rights reserved.
4+ *
5+ * This source code is licensed under the BSD-style license found in the
6+ * LICENSE file in the root directory of this source tree. An additional grant
7+ * of patent rights can be found in the PATENTS file in the same directory.
8+ */
9+
10+ using System ;
11+ using Microsoft . AspNet . Builder ;
12+ using Microsoft . AspNet . Hosting ;
13+ using Microsoft . Framework . DependencyInjection ;
14+ using Microsoft . Framework . Runtime ;
15+ using React . Exceptions ;
16+ using React . TinyIoC ;
17+
18+ namespace React . AspNet
19+ {
20+ /// <summary>
21+ /// Handles registering ReactJS.NET middleware in an ASP.NET <see cref="IApplicationBuilder"/>.
22+ /// </summary>
23+ public static class ReactBuilderExtensions
24+ {
25+ /// <summary>
26+ /// Initialises ReactJS.NET for this application
27+ /// </summary>
28+ /// <param name="app">ASP.NET application builder</param>
29+ /// <param name="configure">ReactJS.NET configuration</param>
30+ /// <param name="fileOptions">Options to use for serving JSX files</param>
31+ /// <returns>The application builder (for chaining)</returns>
32+ public static IApplicationBuilder UseReact (
33+ this IApplicationBuilder app ,
34+ Action < IReactSiteConfiguration > configure ,
35+ JsxFileOptions fileOptions = null
36+ )
37+ {
38+ EnsureServicesRegistered ( app ) ;
39+
40+ // Register IApplicationEnvironment in our dependency injection container
41+ // Ideally this would be in AddReact(IServiceCollection) but we can't
42+ // access IApplicationEnvironment there.
43+ React . AssemblyRegistration . Container . Register ( app . ApplicationServices . GetRequiredService < IApplicationEnvironment > ( ) ) ;
44+ React . AssemblyRegistration . Container . Register ( app . ApplicationServices . GetRequiredService < IHostingEnvironment > ( ) ) ;
45+
46+ Initializer . Initialize ( registerOptions => AsPerRequestSingleton ( app . ApplicationServices , registerOptions ) ) ;
47+ configure ( ReactSiteConfiguration . Configuration ) ;
48+
49+ // Allow serving of .jsx files
50+ app . UseMiddleware < JsxFileMiddleware > ( fileOptions ?? new JsxFileOptions ( ) ) ;
51+
52+ return app ;
53+ }
54+
55+ /// <summary>
56+ /// Registers a class such that every ASP.NET web request has a single instance of it.
57+ /// </summary>
58+ /// <param name="appServiceProvider">ASP.NET service provider</param>
59+ /// <param name="registerOptions">Registration options</param>
60+ /// <returns>Registration options (for chaining)</returns>
61+ private static TinyIoCContainer . RegisterOptions AsPerRequestSingleton (
62+ IServiceProvider appServiceProvider ,
63+ TinyIoCContainer . RegisterOptions registerOptions
64+ )
65+ {
66+ return TinyIoCContainer . RegisterOptions . ToCustomLifetimeManager (
67+ registerOptions ,
68+ new HttpContextLifetimeProvider ( appServiceProvider ) ,
69+ "per request singleton"
70+ ) ;
71+ }
72+
73+ /// <summary>
74+ /// Ensures React services have been registered in the ASP.NET dependency injection container.
75+ /// </summary>
76+ /// <param name="app">ASP.NET application builder</param>
77+ private static void EnsureServicesRegistered ( IApplicationBuilder app )
78+ {
79+ var registrations = app . ApplicationServices . GetService < HttpContextLifetimeProvider . PerRequestRegistrations > ( ) ;
80+ if ( registrations == null )
81+ {
82+ throw new ReactNotInitialisedException ( "Please call app.AddReact() before app.UseReact()." ) ;
83+ }
84+ }
85+ }
86+ }
0 commit comments