Преглед изворни кода

half-commit: *broken* WIP hot-load

Local пре 5 година
родитељ
комит
29ece29843

+ 0 - 5
AspNetCoreDefaultHost/Configs/HostConfig.cs

@@ -55,11 +55,6 @@ namespace AspNetCoreDefaultHost.Configs
                 logger.LogInformation($"Initializing component `{component.GetType().FullName}'");
                 component.Init();
             }
-
-#if !EMBED_HTML
-            //TODO: Monitoring file change & hot reload
-            logger.LogDebug("TODO: watching html and hot reload");
-#endif
         }
 
         private static void LoadGlobalConfig(SimpleDataBindContext dbc)

+ 55 - 0
AspNetCoreSsrTemplateEngine/Template/HotLoadTemplate.cs

@@ -0,0 +1,55 @@
+using System;
+using AspNetCoreSsrTemplateEngine.DataBoundContext;
+using AspNetCoreSsrTemplateEngine.Renders;
+using System.Collections.Generic;
+using System.IO;
+using System.Threading.Tasks;
+
+namespace AspNetCoreSsrTemplateEngine.Template
+{
+#if !EMBED_HTML
+
+    public class HotLoadTemplate : ITemplate,IDisposable
+    {
+        private readonly string _fullTypeName;
+        private readonly IComponentResolver _componentResolver;
+        private readonly FileSystemWatcher _fileSystemWatcher;
+
+        public IReadOnlyList<IRender> RenderSequence { get; private set; }
+
+        public HotLoadTemplate(string fullTypeName, IComponentResolver componentResolver)
+        {
+            _fullTypeName = fullTypeName;
+            _componentResolver = componentResolver;
+            Reload();
+            var templateFilePath = TemplateLoader.GetTemplateFilePath(fullTypeName);
+            _fileSystemWatcher = new FileSystemWatcher(templateFilePath);
+            _fileSystemWatcher.Changed += _fileSystemWatcher_Changed;
+        }
+
+        private void _fileSystemWatcher_Changed(object sender, FileSystemEventArgs e)
+        {
+            if (e.ChangeType == WatcherChangeTypes.Changed) Reload();
+        }
+
+        private void Reload()
+        {
+            RenderSequence = TemplateLoader.LoadByFullTypeName(_fullTypeName, _componentResolver);
+        }
+
+        public async Task RenderAsync(IReadonlyDataBindContext dataBindContext, Stream stream)
+        {
+            foreach (var render in RenderSequence)
+            {
+                await render.RenderAsync(dataBindContext, stream);
+            }
+        }
+
+        public void Dispose()
+        {
+            _fileSystemWatcher?.Dispose();
+        }
+    }
+
+#endif
+}

+ 30 - 9
AspNetCoreSsrTemplateEngine/Template/TemplateLoader.cs

@@ -1,9 +1,9 @@
-using System;
+using AspNetCoreSsrTemplateEngine.Renders;
+using System;
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
 using System.Text.RegularExpressions;
-using AspNetCoreSsrTemplateEngine.Renders;
 
 namespace AspNetCoreSsrTemplateEngine.Template
 {
@@ -17,28 +17,49 @@ namespace AspNetCoreSsrTemplateEngine.Template
         {
             if (instance == null) throw new ArgumentNullException(nameof(instance));
 
-            var template = LoadTemplateResource(instance);
+            var fullTypeName = instance.GetType().FullName;
 
-            return new SimpleTemplate(ParseInternal(template, componentResolver));
+#if !EMBED_HTML
+            return new HotLoadTemplate(fullTypeName, componentResolver);
+#else
+            return new SimpleTemplate(LoadByFullTypeName(fullTypeName, componentResolver));
+#endif
         }
 
-        private static string LoadTemplateResource(object instance)
+        internal static IRender[] LoadByFullTypeName(string fullTypeName, IComponentResolver componentResolver)
         {
-            var typeFullName = instance.GetType().FullName ?? throw new InvalidOperationException("Class full name is null?");
+            var template = LoadTemplateResource(fullTypeName);
+            var seq = ParseInternal(template, componentResolver);
+            return seq;
+        }
 
+        private static string LoadTemplateResource(string typeFullName)
+        {
 #if EMBED_HTML
             var asm = instance.GetType().Assembly;
             var manifestResourceStream = asm.GetManifestResourceStream(typeFullName);
             if (null == manifestResourceStream) throw new System.Resources.MissingManifestResourceException($"resource `{typeFullName}' not found");
             var template = Utils.StreamExtensionMethod.ReadUtf8(manifestResourceStream);
 #else
-            var projectDir = Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "../../../../"));
-            var template = File.ReadAllText(Path.Combine(projectDir, typeFullName.Replace(".", "/") + FileExtension));
+            var path = GetTemplateFilePath(typeFullName);
+            var template = File.ReadAllText(path);
 #endif
             return template;
         }
 
-        private static IRender[] ParseInternal(string template, IComponentResolver componentResolver)
+#if !EMBED_HTML
+
+        internal static string GetTemplateFilePath(string typeFullName)
+        {
+            var projectDir = Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "../../../../"));
+            var path = Path.Combine(projectDir, typeFullName.Replace(".", "/") + FileExtension);
+
+            return Path.GetFullPath(path);
+        }
+
+#endif
+
+        internal static IRender[] ParseInternal(string template, IComponentResolver componentResolver)
         {
             var comments = ParseRegex.Matches(template).OrderBy(p => p.Index);