diff --git a/system/Bootstrap.cfc b/system/Bootstrap.cfc index 5f53d35bd..4bb6da743 100644 --- a/system/Bootstrap.cfc +++ b/system/Bootstrap.cfc @@ -191,7 +191,7 @@ component serializable="false" accessors="true" { // WireBox Singleton AutoReload if ( cbController.getSetting( "Wirebox" ).singletonReload ) { lock type="exclusive" name="#appHash#" timeout="#lockTimeout#" throwontimeout="true" { - cbController.getWireBox().clearSingletons(); + cbController.getWireBox().clearAppSingletons(); } } // Handler's Index Auto Reload diff --git a/system/ioc/Injector.cfc b/system/ioc/Injector.cfc index 98f80cfbf..540cc43ea 100644 --- a/system/ioc/Injector.cfc +++ b/system/ioc/Injector.cfc @@ -1068,6 +1068,14 @@ component serializable="false" accessors="true" { return this; } + /** + * Clear the app singleton cache + */ + Injector function clearAppSingletons(){ + getScope( "SINGLETON" ).clearAppOnly(); + return this; + } + /** * Return a self reference using the scoped registration, mostly used by providers or scope widening objects * diff --git a/system/ioc/scopes/Singleton.cfc b/system/ioc/scopes/Singleton.cfc index 23c763f1a..532a45fc0 100644 --- a/system/ioc/scopes/Singleton.cfc +++ b/system/ioc/scopes/Singleton.cfc @@ -23,6 +23,11 @@ component accessors="true" { */ property name="log"; + /** + * These are keys we use internally in ColdBox, so we don't want to clear them when doing clearAppOnly() calls + */ + variables.RESERVED_KEYS = [ "@coldbox", "interceptor-", "cbscheduler", "@coreDelegates", "@cbdelegates" ]; + /** * Configure the scope for operation and returns itself * @@ -133,4 +138,29 @@ component accessors="true" { return this; } + /** + * Clear application only singletons + */ + function clearAppOnly(){ + var keys = variables.singletons.keySet().toArray(); + for( var key in keys ){ + // They key must NOT match any pattern in our reserved keys, so we can clear it + if( !inReservedKeys( key ) ){ + variables.singletons.remove( key ); + } + } + return this; + } + + /** + * Discover if a key is in our reserved keys + * + * @key The key to check + * + * @return boolean + */ + private boolean function inReservedKeys( String key ){ + return variables.RESERVED_KEYS.some( ( reservedKey ) => findNoCase( reservedKey, key ) ); + } + } diff --git a/test-harness/config/Coldbox.cfc b/test-harness/config/Coldbox.cfc index 0e5fbede4..2f25834fe 100644 --- a/test-harness/config/Coldbox.cfc +++ b/test-harness/config/Coldbox.cfc @@ -144,5 +144,8 @@ } function development(){ + wirebox = { + singletonReload : true + } } }