diff --git a/build.proj b/build.proj index dd156a7ed..b642b5b73 100644 --- a/build.proj +++ b/build.proj @@ -10,8 +10,8 @@ of patent rights can be found in the PATENTS file in the same directory. 3 - 0 - 1 + 1 + 0 0 http://reactjs.net/packages/ $(MSBuildProjectDirectory)\tools\MSBuildTasks diff --git a/src/React.Core/IJavaScriptEngineFactory.cs b/src/React.Core/IJavaScriptEngineFactory.cs index bb29e05eb..adb731d3a 100644 --- a/src/React.Core/IJavaScriptEngineFactory.cs +++ b/src/React.Core/IJavaScriptEngineFactory.cs @@ -1,5 +1,5 @@ -using System; -using JavaScriptEngineSwitcher.Core; +using JavaScriptEngineSwitcher.Core; +using JSPool; namespace React { @@ -25,12 +25,6 @@ public interface IJavaScriptEngineFactory /// Gets a JavaScript engine from the pool. /// /// The JavaScript engine - IJsEngine GetEngine(); - - /// - /// Returns an engine to the pool so it can be reused - /// - /// Engine to return - void ReturnEngineToPool(IJsEngine engine); + PooledJsEngine GetEngine(); } } \ No newline at end of file diff --git a/src/React.Core/JavaScriptEngineFactory.cs b/src/React.Core/JavaScriptEngineFactory.cs index 073f7b791..98d1ce575 100644 --- a/src/React.Core/JavaScriptEngineFactory.cs +++ b/src/React.Core/JavaScriptEngineFactory.cs @@ -223,26 +223,12 @@ public virtual void DisposeEngineForCurrentThread() /// Gets a JavaScript engine from the pool. /// /// The JavaScript engine - public virtual IJsEngine GetEngine() + public virtual PooledJsEngine GetEngine() { EnsureValidState(); return _pool.GetEngine(); } - /// - /// Returns an engine to the pool so it can be reused - /// - /// Engine to return - public virtual void ReturnEngineToPool(IJsEngine engine) - { - // This could be called from ReactEnvironment.Dispose if that class is disposed after - // this class. Let's just ignore this if it's disposed. - if (!_disposed) - { - _pool.ReturnEngineToPool(engine); - } - } - /// /// Gets a factory for the most appropriate JavaScript engine for the current environment. /// The first functioning JavaScript engine with the lowest priority will be used. diff --git a/src/React.Core/React.Core.csproj b/src/React.Core/React.Core.csproj index a37903822..a73d7e5d9 100644 --- a/src/React.Core/React.Core.csproj +++ b/src/React.Core/React.Core.csproj @@ -26,16 +26,16 @@ - - - - - + + + + + - + diff --git a/src/React.Core/ReactEnvironment.cs b/src/React.Core/ReactEnvironment.cs index c6decd161..97d8cc296 100644 --- a/src/React.Core/ReactEnvironment.cs +++ b/src/React.Core/ReactEnvironment.cs @@ -15,6 +15,7 @@ using System.Threading; using JavaScriptEngineSwitcher.Core; using JavaScriptEngineSwitcher.Core.Helpers; +using JSPool; using Newtonsoft.Json; using React.Exceptions; @@ -68,7 +69,7 @@ public class ReactEnvironment : IReactEnvironment, IDisposable /// Contains an engine acquired from a pool of engines. Only used if /// is enabled. /// - protected Lazy _engineFromPool; + protected Lazy _engineFromPool; /// /// List of all components instantiated in this environment @@ -108,7 +109,7 @@ IFileCacheHash fileCacheHash _babelTransformer = new Lazy(() => new Babel(this, _cache, _fileSystem, _fileCacheHash, _config) ); - _engineFromPool = new Lazy(() => _engineFactory.GetEngine()); + _engineFromPool = new Lazy(() => _engineFactory.GetEngine()); } /// @@ -399,8 +400,8 @@ public void ReturnEngineToPool() { if (_engineFromPool.IsValueCreated) { - _engineFactory.ReturnEngineToPool(_engineFromPool.Value); - _engineFromPool = new Lazy(() => _engineFactory.GetEngine()); + _engineFromPool.Value.Dispose(); + _engineFromPool = new Lazy(() => _engineFactory.GetEngine()); } } diff --git a/src/React.MSBuild/AssemblyBindingRedirect.cs b/src/React.MSBuild/AssemblyBindingRedirect.cs new file mode 100644 index 000000000..c88a85d6b --- /dev/null +++ b/src/React.MSBuild/AssemblyBindingRedirect.cs @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2017-Present, 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 System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Reflection; + +namespace React.MSBuild +{ + /// + /// Hacks around the fact that it's not possible to do assembly binding redirects in MSBuild. + /// + /// https://github.com/Microsoft/msbuild/issues/1309 + /// http://blog.slaks.net/2013-12-25/redirecting-assembly-loads-at-runtime/ + /// + public static class AssemblyBindingRedirect + { + /// + /// Redirects that have been configured + /// + private static readonly Dictionary _redirects = new Dictionary(); + + static AssemblyBindingRedirect() + { + // This is in a static constructor because it needs to run as early as possible + ConfigureRedirect("JavaScriptEngineSwitcher.Core"); + AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; + } + + /// + /// Enables assembly binding redirects + /// + public static void Enable() + { + // Intentionally empty. This is just meant to ensure the static constructor + // has run. + } + + /// + /// Configures a redirect for the specified assembly. Redirects to the version in the bin directory. + /// + /// Name of the assembly to redirect + private static void ConfigureRedirect(string name) + { + var currentAssemblyPath = Assembly.GetExecutingAssembly().Location; + var redirectAssemblyPath = Path.Combine( + Path.GetDirectoryName(currentAssemblyPath), + name + ".dll" + ); + + try + { + var realAssembly = Assembly.LoadFile(redirectAssemblyPath); + var version = realAssembly.GetName().Version; + _redirects[name] = version; + } + catch (Exception ex) + { + Trace.WriteLine("Warning: Could not determine version of " + name + " to use! " + ex.Message); + } + } + + /// + /// Overrides assembly resolution to redirect if necessary. + /// + private static Assembly ResolveAssembly(object sender, ResolveEventArgs args) + { + var requestedAssembly = new AssemblyName(args.Name); + + if (_redirects.ContainsKey(requestedAssembly.Name) && requestedAssembly.Version != _redirects[requestedAssembly.Name]) + { + requestedAssembly.Version = _redirects[requestedAssembly.Name]; + return Assembly.Load(requestedAssembly); + } + return null; + } + } +} diff --git a/src/React.MSBuild/MSBuildHost.cs b/src/React.MSBuild/MSBuildHost.cs index 75668032f..291f5191a 100644 --- a/src/React.MSBuild/MSBuildHost.cs +++ b/src/React.MSBuild/MSBuildHost.cs @@ -9,6 +9,7 @@ using System; using System.Diagnostics; +using System.Reflection; namespace React.MSBuild { @@ -36,6 +37,8 @@ public static bool EnsureInitialized() /// private static bool Initialize() { + AssemblyBindingRedirect.Enable(); + // All "per-request" registrations should be singletons in MSBuild, since there's no // such thing as a "request" Initializer.Initialize(requestLifetimeRegistration: registration => registration.AsSingleton()); diff --git a/src/React.Sample.Cassette/React.Sample.Cassette.csproj b/src/React.Sample.Cassette/React.Sample.Cassette.csproj index 1f73c5138..6113ea009 100644 --- a/src/React.Sample.Cassette/React.Sample.Cassette.csproj +++ b/src/React.Sample.Cassette/React.Sample.Cassette.csproj @@ -68,9 +68,8 @@ ..\packages\Cassette.Views.2.4.2\lib\net40\Cassette.Views.dll True - - ..\packages\JavaScriptEngineSwitcher.Core.2.2.0\lib\net40-client\JavaScriptEngineSwitcher.Core.dll - True + + ..\packages\JavaScriptEngineSwitcher.Core.2.4.9\lib\net40-client\JavaScriptEngineSwitcher.Core.dll diff --git a/src/React.Sample.Cassette/Web.config b/src/React.Sample.Cassette/Web.config index 76ddce629..03f710621 100644 --- a/src/React.Sample.Cassette/Web.config +++ b/src/React.Sample.Cassette/Web.config @@ -62,7 +62,7 @@ - + diff --git a/src/React.Sample.Cassette/packages.config b/src/React.Sample.Cassette/packages.config index 33d421787..6a88d2bbd 100644 --- a/src/React.Sample.Cassette/packages.config +++ b/src/React.Sample.Cassette/packages.config @@ -5,7 +5,7 @@ - + diff --git a/src/React.Sample.Mvc4/React.Sample.Mvc4.csproj b/src/React.Sample.Mvc4/React.Sample.Mvc4.csproj index 99491c500..ff0d460cf 100644 --- a/src/React.Sample.Mvc4/React.Sample.Mvc4.csproj +++ b/src/React.Sample.Mvc4/React.Sample.Mvc4.csproj @@ -57,26 +57,21 @@ ..\packages\Antlr.3.5.0.2\lib\Antlr3.Runtime.dll True - - ..\packages\JavaScriptEngineSwitcher.V8.2.2.0\lib\net45\ClearScript.dll - True + + ..\packages\JavaScriptEngineSwitcher.V8.2.4.2\lib\net45\ClearScript.dll - - ..\packages\JavaScriptEngineSwitcher.Core.2.2.0\lib\net45\JavaScriptEngineSwitcher.Core.dll - True + + ..\packages\JavaScriptEngineSwitcher.Core.2.4.9\lib\net45\JavaScriptEngineSwitcher.Core.dll - - ..\packages\JavaScriptEngineSwitcher.Msie.2.3.2\lib\net45\JavaScriptEngineSwitcher.Msie.dll - True + + ..\packages\JavaScriptEngineSwitcher.Msie.2.4.9\lib\net45\JavaScriptEngineSwitcher.Msie.dll - - ..\packages\JavaScriptEngineSwitcher.V8.2.2.0\lib\net45\JavaScriptEngineSwitcher.V8.dll - True + + ..\packages\JavaScriptEngineSwitcher.V8.2.4.2\lib\net45\JavaScriptEngineSwitcher.V8.dll - - ..\packages\MsieJavaScriptEngine.2.1.2\lib\net45\MsieJavaScriptEngine.dll - True + + ..\packages\MsieJavaScriptEngine.2.2.2\lib\net45\MsieJavaScriptEngine.dll ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll diff --git a/src/React.Sample.Mvc4/Web.config b/src/React.Sample.Mvc4/Web.config index b0d911789..a763dbb65 100644 --- a/src/React.Sample.Mvc4/Web.config +++ b/src/React.Sample.Mvc4/Web.config @@ -74,7 +74,7 @@ - + @@ -92,6 +92,10 @@ + + + + diff --git a/src/React.Sample.Mvc4/packages.config b/src/React.Sample.Mvc4/packages.config index 9afda2981..829d1c97e 100644 --- a/src/React.Sample.Mvc4/packages.config +++ b/src/React.Sample.Mvc4/packages.config @@ -1,15 +1,15 @@  - - - + + + - + diff --git a/src/React.Sample.Mvc6/React.Sample.Mvc6.csproj b/src/React.Sample.Mvc6/React.Sample.Mvc6.csproj index 054c5ba70..49d1d1e14 100644 --- a/src/React.Sample.Mvc6/React.Sample.Mvc6.csproj +++ b/src/React.Sample.Mvc6/React.Sample.Mvc6.csproj @@ -37,7 +37,7 @@ - + diff --git a/src/React.Sample.Webpack/React.Sample.Webpack.csproj b/src/React.Sample.Webpack/React.Sample.Webpack.csproj index 05bf0b2f6..47331ef8e 100644 --- a/src/React.Sample.Webpack/React.Sample.Webpack.csproj +++ b/src/React.Sample.Webpack/React.Sample.Webpack.csproj @@ -50,17 +50,14 @@ 1607 - - ..\packages\JavaScriptEngineSwitcher.V8.2.2.0\lib\net40-client\ClearScript.dll - True + + ..\packages\JavaScriptEngineSwitcher.V8.2.4.2\lib\net40-client\ClearScript.dll - - ..\packages\JavaScriptEngineSwitcher.Core.2.2.0\lib\net40-client\JavaScriptEngineSwitcher.Core.dll - True + + ..\packages\JavaScriptEngineSwitcher.Core.2.4.9\lib\net40-client\JavaScriptEngineSwitcher.Core.dll - - ..\packages\JavaScriptEngineSwitcher.V8.2.2.0\lib\net40-client\JavaScriptEngineSwitcher.V8.dll - True + + ..\packages\JavaScriptEngineSwitcher.V8.2.4.2\lib\net40-client\JavaScriptEngineSwitcher.V8.dll diff --git a/src/React.Sample.Webpack/Web.config b/src/React.Sample.Webpack/Web.config index 4c4c68666..1c1eaf3d2 100644 --- a/src/React.Sample.Webpack/Web.config +++ b/src/React.Sample.Webpack/Web.config @@ -56,7 +56,7 @@ - + diff --git a/src/React.Sample.Webpack/packages.config b/src/React.Sample.Webpack/packages.config index 219b3ba3b..1d68f8292 100644 --- a/src/React.Sample.Webpack/packages.config +++ b/src/React.Sample.Webpack/packages.config @@ -1,7 +1,7 @@  - - + + diff --git a/tests/React.Tests/Core/ReactEnvironmentTest.cs b/tests/React.Tests/Core/ReactEnvironmentTest.cs index a8b478491..5829d21d2 100644 --- a/tests/React.Tests/Core/ReactEnvironmentTest.cs +++ b/tests/React.Tests/Core/ReactEnvironmentTest.cs @@ -11,6 +11,7 @@ using System.Collections.Generic; using System.Linq; using JavaScriptEngineSwitcher.Core; +using JSPool; using Moq; using Xunit; using React.Exceptions; @@ -124,7 +125,7 @@ public void ReturnsEngineToPool() private class Mocks { - public Mock Engine { get; private set; } + public Mock Engine { get; private set; } public Mock EngineFactory { get; private set; } public Mock Config { get; private set; } public Mock Cache { get; private set; } @@ -132,7 +133,7 @@ private class Mocks public Mock FileCacheHash { get; private set; } public Mocks() { - Engine = new Mock(); + Engine = new Mock(); EngineFactory = new Mock(); Config = new Mock(); Cache = new Mock();