@@ -36,22 +36,22 @@ public sealed class DotNetFunctionInvoker : FunctionInvokerBase
3636 private FunctionSignature _functionSignature ;
3737 private IFunctionMetadataResolver _metadataResolver ;
3838 private Action _reloadScript ;
39+ private Action _shutdown ;
3940 private Action _restorePackages ;
4041 private Action < MethodInfo , object [ ] , object [ ] , object > _resultProcessor ;
4142 private string [ ] _watchedFileTypes ;
4243
43- private static readonly string [ ] AssemblyFileTypes = { ".dll" , ".exe" } ;
44-
4544 internal DotNetFunctionInvoker ( ScriptHost host , FunctionMetadata functionMetadata ,
4645 Collection < FunctionBinding > inputBindings , Collection < FunctionBinding > outputBindings ,
4746 IFunctionEntryPointResolver functionEntryPointResolver , FunctionAssemblyLoader assemblyLoader ,
48- ICompilationServiceFactory compilationServiceFactory , ITraceWriterFactory traceWriterFactory = null )
47+ ICompilationServiceFactory compilationServiceFactory , ITraceWriterFactory traceWriterFactory = null ,
48+ IFunctionMetadataResolver metadataResolver = null )
4949 : base ( host , functionMetadata , traceWriterFactory )
5050 {
5151 _metricsLogger = Host . ScriptConfig . HostConfig . GetService < IMetricsLogger > ( ) ;
5252 _functionEntryPointResolver = functionEntryPointResolver ;
5353 _assemblyLoader = assemblyLoader ;
54- _metadataResolver = new FunctionMetadataResolver ( functionMetadata , host . ScriptConfig . BindingProviders , TraceWriter ) ;
54+ _metadataResolver = metadataResolver ?? new FunctionMetadataResolver ( functionMetadata , host . ScriptConfig . BindingProviders , TraceWriter ) ;
5555 _compilationService = compilationServiceFactory . CreateService ( functionMetadata . ScriptType , _metadataResolver ) ;
5656 _inputBindings = inputBindings ;
5757 _outputBindings = outputBindings ;
@@ -66,6 +66,9 @@ internal DotNetFunctionInvoker(ScriptHost host, FunctionMetadata functionMetadat
6666 _reloadScript = ReloadScript ;
6767 _reloadScript = _reloadScript . Debounce ( ) ;
6868
69+ _shutdown = ( ) => Host . Shutdown ( ) ;
70+ _shutdown = _shutdown . Debounce ( ) ;
71+
6972 _restorePackages = RestorePackages ;
7073 _restorePackages = _restorePackages . Debounce ( ) ;
7174 }
@@ -74,7 +77,7 @@ private void InitializeFileWatcher()
7477 {
7578 if ( InitializeFileWatcherIfEnabled ( ) )
7679 {
77- _watchedFileTypes = AssemblyFileTypes
80+ _watchedFileTypes = ScriptConstants . AssemblyFileTypes
7881 . Concat ( _compilationService . SupportedFileTypes )
7982 . ToArray ( ) ;
8083 }
@@ -84,7 +87,14 @@ protected override void OnScriptFileChanged(object sender, FileSystemEventArgs e
8487 {
8588 // The ScriptHost is already monitoring for changes to function.json, so we skip those
8689 string fileExtension = Path . GetExtension ( e . Name ) ;
87- if ( _watchedFileTypes . Contains ( fileExtension ) )
90+ if ( ScriptConstants . AssemblyFileTypes . Contains ( fileExtension , StringComparer . OrdinalIgnoreCase ) )
91+ {
92+ TraceWriter . Info ( "Assembly changes detected. Restarting host..." ) ;
93+
94+ // As a result of an assembly change, we initiate a full host shutdown
95+ _shutdown ( ) ;
96+ }
97+ else if ( _watchedFileTypes . Contains ( fileExtension ) )
8898 {
8999 _reloadScript ( ) ;
90100 }
@@ -146,7 +156,7 @@ private void ReloadScript()
146156 ( _functionSignature == null ||
147157 ( _functionSignature . HasLocalTypeReference || ! _functionSignature . Equals ( signature ) ) ) )
148158 {
149- Host . RestartEvent . Set ( ) ;
159+ Host . Restart ( ) ;
150160 }
151161 }
152162
@@ -172,19 +182,31 @@ private void RestorePackages()
172182 . ContinueWith ( t => t . Exception . Handle ( e => true ) , TaskContinuationOptions . OnlyOnFaulted | TaskContinuationOptions . ExecuteSynchronously ) ;
173183 }
174184
175- private async Task RestorePackagesAsync ( bool reloadScriptOnSuccess = true )
185+ internal async Task RestorePackagesAsync ( bool reloadScriptOnSuccess = true )
176186 {
177187 TraceOnPrimaryHost ( "Restoring packages." , TraceLevel . Info ) ;
178188
179189 try
180190 {
181- await _metadataResolver . RestorePackagesAsync ( ) ;
191+ PackageRestoreResult result = await _metadataResolver . RestorePackagesAsync ( ) ;
182192
183193 TraceOnPrimaryHost ( "Packages restored." , TraceLevel . Info ) ;
184194
185195 if ( reloadScriptOnSuccess )
186196 {
187- _reloadScript ( ) ;
197+ if ( ! result . IsInitialInstall && result . ReferencesChanged )
198+ {
199+ TraceOnPrimaryHost ( "Package references have changed. Restarting host..." , TraceLevel . Info ) ;
200+
201+ // If this is not the initial package install and references changed,
202+ // shutdown the host, which will cause it to have a clean start and load the new
203+ // assembly references
204+ _shutdown ( ) ;
205+ }
206+ else
207+ {
208+ _reloadScript ( ) ;
209+ }
188210 }
189211 }
190212 catch ( Exception exc )
0 commit comments