diff --git a/src/Microsoft.Framework.DesignTimeHost/ApplicationContext.cs b/src/Microsoft.Framework.DesignTimeHost/ApplicationContext.cs index d56d20770..f9488e54c 100644 --- a/src/Microsoft.Framework.DesignTimeHost/ApplicationContext.cs +++ b/src/Microsoft.Framework.DesignTimeHost/ApplicationContext.cs @@ -25,6 +25,8 @@ public class ApplicationContext { private readonly IServiceProvider _hostServices; private readonly ICache _cache; + private readonly ICacheContextAccessor _cacheContextAccessor; + private readonly Queue _inbox = new Queue(); private readonly object _processingLock = new object(); @@ -42,10 +44,11 @@ public class ApplicationContext private readonly List _waitingForCompiledAssemblies = new List(); private readonly List _waitingForDiagnostics = new List(); - public ApplicationContext(IServiceProvider services, ICache cache, int id) + public ApplicationContext(IServiceProvider services, ICache cache, ICacheContextAccessor cacheContextAccessor, int id) { _hostServices = services; _cache = cache; + _cacheContextAccessor = cacheContextAccessor; Id = id; } @@ -501,7 +504,8 @@ private State Initialize(string appPath, FrameworkName targetFramework, string c packagesDirectory: null, configuration: configuration, targetFramework: targetFramework, - cache: _cache); + cache: _cache, + cacheContextAccessor: _cacheContextAccessor); Project project = applicationHostContext.Project; diff --git a/src/Microsoft.Framework.DesignTimeHost/ConnectionContext.cs b/src/Microsoft.Framework.DesignTimeHost/ConnectionContext.cs index 8f017cf28..2ebd3c380 100644 --- a/src/Microsoft.Framework.DesignTimeHost/ConnectionContext.cs +++ b/src/Microsoft.Framework.DesignTimeHost/ConnectionContext.cs @@ -15,18 +15,21 @@ public class ConnectionContext private readonly IDictionary _contexts; private readonly IServiceProvider _services; private readonly ICache _cache; + private readonly ICacheContextAccessor _cacheContextAccessor; private ProcessingQueue _queue; private string _hostId; public ConnectionContext(IDictionary contexts, IServiceProvider services, ICache cache, + ICacheContextAccessor cacheContextAccessor, ProcessingQueue queue, string hostId) { _contexts = contexts; _services = services; _cache = cache; + _cacheContextAccessor = cacheContextAccessor; _queue = queue; _hostId = hostId; } @@ -53,7 +56,11 @@ public void OnReceive(Message message) { Trace.TraceInformation("[ConnectionContext]: Creating new application context for {0}", message.ContextId); - applicationContext = new ApplicationContext(_services, _cache, message.ContextId); + applicationContext = new ApplicationContext(_services, + _cache, + _cacheContextAccessor, + message.ContextId); + _contexts.Add(message.ContextId, applicationContext); } diff --git a/src/Microsoft.Framework.DesignTimeHost/Program.cs b/src/Microsoft.Framework.DesignTimeHost/Program.cs index 7c311d637..c5b01f07b 100644 --- a/src/Microsoft.Framework.DesignTimeHost/Program.cs +++ b/src/Microsoft.Framework.DesignTimeHost/Program.cs @@ -47,7 +47,8 @@ public void Main(string[] args) private async Task OpenChannel(int port, string hostId) { - var cache = new Cache(); + var cacheContextAccessor = new CacheContextAccessor(); + var cache = new Cache(cacheContextAccessor); var contexts = new Dictionary(); // This fixes the mono incompatibility but ties it to ipv4 connections @@ -65,7 +66,7 @@ private async Task OpenChannel(int port, string hostId) var stream = new NetworkStream(acceptSocket); var queue = new ProcessingQueue(stream); - var connection = new ConnectionContext(contexts, _services, cache, queue, hostId); + var connection = new ConnectionContext(contexts, _services, cache, cacheContextAccessor, queue, hostId); queue.OnReceive += message => { diff --git a/src/Microsoft.Framework.PackageManager/Building/BuildContext.cs b/src/Microsoft.Framework.PackageManager/Building/BuildContext.cs index 7a96a526f..7febfc553 100644 --- a/src/Microsoft.Framework.PackageManager/Building/BuildContext.cs +++ b/src/Microsoft.Framework.PackageManager/Building/BuildContext.cs @@ -17,7 +17,7 @@ public class BuildContext private readonly string _outputPath; private readonly ApplicationHostContext _applicationHostContext; - public BuildContext(ICache cache, Project project, FrameworkName targetFramework, string configuration, string outputPath) + public BuildContext(ICache cache, ICacheContextAccessor cacheContextAccessor, Project project, FrameworkName targetFramework, string configuration, string outputPath) { _project = project; _targetFramework = targetFramework; @@ -30,7 +30,8 @@ public BuildContext(ICache cache, Project project, FrameworkName targetFramework packagesDirectory: null, configuration: configuration, targetFramework: targetFramework, - cache: cache); + cache: cache, + cacheContextAccessor: cacheContextAccessor); } public void Initialize() diff --git a/src/Microsoft.Framework.PackageManager/Building/BuildManager.cs b/src/Microsoft.Framework.PackageManager/Building/BuildManager.cs index 943309b0a..2f39fc4f1 100644 --- a/src/Microsoft.Framework.PackageManager/Building/BuildManager.cs +++ b/src/Microsoft.Framework.PackageManager/Building/BuildManager.cs @@ -94,7 +94,8 @@ public bool Build() host.Initialize(); - var cache = new Cache(); + var cacheContextAccessor = new CacheContextAccessor(); + var cache = new Cache(cacheContextAccessor); using (host.AddLoaders(loaderContainer)) { @@ -118,7 +119,12 @@ public bool Build() var errors = new List(); var warnings = new List(); - var context = new BuildContext(cache, project, targetFramework, configuration, baseOutputPath); + var context = new BuildContext(cache, + cacheContextAccessor, + project, + targetFramework, + configuration, + baseOutputPath); context.Initialize(); if (_buildOptions.CheckDiagnostics) diff --git a/src/Microsoft.Framework.PackageManager/Packing/PackManager.cs b/src/Microsoft.Framework.PackageManager/Packing/PackManager.cs index d4f31644c..6250f2af3 100644 --- a/src/Microsoft.Framework.PackageManager/Packing/PackManager.cs +++ b/src/Microsoft.Framework.PackageManager/Packing/PackManager.cs @@ -41,13 +41,17 @@ public class DependencyContext { public DependencyContext(string projectDirectory, string configuration, FrameworkName targetFramework) { + var cacheContextAccessor = new CacheContextAccessor(); + var cache = new Cache(cacheContextAccessor); + var applicationHostContext = new ApplicationHostContext( serviceProvider: null, projectDirectory: projectDirectory, packagesDirectory: null, configuration: configuration, targetFramework: targetFramework, - cache: new Cache()); + cache: cache, + cacheContextAccessor: cacheContextAccessor); ProjectResolver = applicationHostContext.ProjectResolver; NuGetDependencyResolver = applicationHostContext.NuGetDependencyProvider; diff --git a/src/Microsoft.Framework.Runtime.Roslyn/RoslynCompiler.cs b/src/Microsoft.Framework.Runtime.Roslyn/RoslynCompiler.cs index 698bc1472..92f721425 100644 --- a/src/Microsoft.Framework.Runtime.Roslyn/RoslynCompiler.cs +++ b/src/Microsoft.Framework.Runtime.Roslyn/RoslynCompiler.cs @@ -17,11 +17,15 @@ namespace Microsoft.Framework.Runtime.Roslyn public class RoslynCompiler { private readonly ICache _cache; + private readonly ICacheContextAccessor _cacheContextAccessor; private readonly IFileWatcher _watcher; - public RoslynCompiler(ICache cache, IFileWatcher watcher) + public RoslynCompiler(ICache cache, + ICacheContextAccessor cacheContextAccessor, + IFileWatcher watcher) { _cache = cache; + _cacheContextAccessor = cacheContextAccessor; _watcher = watcher; } @@ -45,13 +49,6 @@ public CompilationContext CompileProject( Trace.TraceInformation("[{0}]: Compiling '{1}'", GetType().Name, name); var sw = Stopwatch.StartNew(); - _watcher.WatchDirectory(path, ".cs"); - - foreach (var directory in Directory.EnumerateDirectories(path, "*.*", SearchOption.AllDirectories)) - { - _watcher.WatchDirectory(directory, ".cs"); - } - var compilationSettings = project.GetCompilationSettings(targetFramework, configuration); IList trees = GetSyntaxTrees(project, compilationSettings, incomingSourceReferences); @@ -128,8 +125,13 @@ private IList GetSyntaxTrees(Project project, var parseOptions = new CSharpParseOptions(languageVersion: compilationSettings.LanguageVersion, preprocessorSymbols: compilationSettings.Defines.AsImmutable()); + var dirs = new HashSet(); + dirs.Add(project.ProjectDirectory); + foreach (var sourcePath in project.SourceFiles) { + dirs.Add(Path.GetDirectoryName(sourcePath)); + _watcher.WatchFile(sourcePath); var syntaxTree = CreateSyntaxTree(sourcePath, parseOptions); @@ -141,6 +143,8 @@ private IList GetSyntaxTrees(Project project, { var sourcePath = sourceFileReference.Path; + dirs.Add(Path.GetDirectoryName(sourcePath)); + _watcher.WatchFile(sourcePath); var syntaxTree = CreateSyntaxTree(sourcePath, parseOptions); @@ -148,6 +152,15 @@ private IList GetSyntaxTrees(Project project, trees.Add(syntaxTree); } + // Watch all directories + var ctx = _cacheContextAccessor.Current; + + foreach (var d in dirs) + { + ctx.Monitor(new FileWriteTimeCacheDependency(d)); + _watcher.WatchDirectory(d, ".cs"); + } + return trees; } diff --git a/src/Microsoft.Framework.Runtime.Roslyn/RoslynProjectReferenceProvider.cs b/src/Microsoft.Framework.Runtime.Roslyn/RoslynProjectReferenceProvider.cs index e879ae25a..5899f833c 100644 --- a/src/Microsoft.Framework.Runtime.Roslyn/RoslynProjectReferenceProvider.cs +++ b/src/Microsoft.Framework.Runtime.Roslyn/RoslynProjectReferenceProvider.cs @@ -8,9 +8,9 @@ public class RoslynProjectReferenceProvider : IProjectReferenceProvider { private readonly RoslynCompiler _compiler; - public RoslynProjectReferenceProvider(ICache cache, IFileWatcher watcher) + public RoslynProjectReferenceProvider(ICache cache, ICacheContextAccessor cacheContextAccessor, IFileWatcher watcher) { - _compiler = new RoslynCompiler(cache, watcher); + _compiler = new RoslynCompiler(cache, cacheContextAccessor, watcher); } public IMetadataProjectReference GetProjectReference( diff --git a/src/Microsoft.Framework.Runtime/ApplicationHostContext.cs b/src/Microsoft.Framework.Runtime/ApplicationHostContext.cs index 799bd8c21..b60d1eb4f 100644 --- a/src/Microsoft.Framework.Runtime/ApplicationHostContext.cs +++ b/src/Microsoft.Framework.Runtime/ApplicationHostContext.cs @@ -17,7 +17,8 @@ public ApplicationHostContext(IServiceProvider serviceProvider, string packagesDirectory, string configuration, FrameworkName targetFramework, - ICache cache) + ICache cache, + ICacheContextAccessor cacheContextAccessor) { ProjectDirectory = projectDirectory; RootDirectory = Runtime.ProjectResolver.ResolveRootDirectory(ProjectDirectory); @@ -59,6 +60,7 @@ public ApplicationHostContext(IServiceProvider serviceProvider, _serviceProvider.Add(typeof(ProjectReferenceDependencyProvider), ProjectDepencyProvider); _serviceProvider.Add(typeof(ILibraryManager), new LibraryManager(targetFramework, configuration, DependencyWalker, compositeDependencyExporter, cache)); _serviceProvider.Add(typeof(ICache), cache); + _serviceProvider.Add(typeof(ICacheContextAccessor), cacheContextAccessor); } public void AddService(Type type, object instance) diff --git a/src/Microsoft.Framework.Runtime/Caching/Cache.cs b/src/Microsoft.Framework.Runtime/Caching/Cache.cs index 341978953..8d806dd4e 100644 --- a/src/Microsoft.Framework.Runtime/Caching/Cache.cs +++ b/src/Microsoft.Framework.Runtime/Caching/Cache.cs @@ -10,10 +10,6 @@ public class Cache : ICache private readonly ConcurrentDictionary> _entries = new ConcurrentDictionary>(); private readonly ICacheContextAccessor _accessor; - public Cache() : this(new CacheContextAccessor()) - { - } - public Cache(ICacheContextAccessor accessor) { _accessor = accessor; diff --git a/src/Microsoft.Framework.Runtime/DefaultHost.cs b/src/Microsoft.Framework.Runtime/DefaultHost.cs index dafe9459e..9045738c3 100644 --- a/src/Microsoft.Framework.Runtime/DefaultHost.cs +++ b/src/Microsoft.Framework.Runtime/DefaultHost.cs @@ -126,13 +126,17 @@ public void Dispose() private void Initialize(DefaultHostOptions options, IServiceProvider hostServices) { + var cacheContextAccessor = new CacheContextAccessor(); + var cache = new Cache(cacheContextAccessor); + _applicationHostContext = new ApplicationHostContext( hostServices, _projectDirectory, options.PackageDirectory, options.Configuration, _targetFramework, - new Cache()); + cache, + cacheContextAccessor); Trace.TraceInformation("[{0}]: Project path: {1}", GetType().Name, _projectDirectory); Trace.TraceInformation("[{0}]: Project root: {1}", GetType().Name, _applicationHostContext.RootDirectory);