Browse Source

Implemented dynamic file provider and in-memory bundling

pull/301/head
Halil ibrahim Kalkan 8 years ago
parent
commit
b71c68f9e4
  1. 25
      src/Volo.Abp.AspNetCore.Mvc.UI/UI/Bundling/BundleManager.cs
  2. 9
      src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/DictionaryBasedFileProvider.cs
  3. 31
      src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/DynamicFileProvider.cs
  4. 36
      src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/InMemoryFileInfo.cs
  5. 43
      src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/VirtualFileProvider.cs

25
src/Volo.Abp.AspNetCore.Mvc.UI/UI/Bundling/BundleManager.cs

@ -12,6 +12,8 @@ using Volo.Abp.AspNetCore.Mvc.UI.Bundling.Styles;
using Volo.Abp.AspNetCore.Mvc.UI.Theming; using Volo.Abp.AspNetCore.Mvc.UI.Theming;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.IO; using Volo.Abp.IO;
using Volo.Abp.VirtualFileSystem;
using Volo.Abp.VirtualFileSystem.Embedded;
namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling
{ {
@ -22,8 +24,8 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling
private readonly IHostingEnvironment _hostingEnvironment; private readonly IHostingEnvironment _hostingEnvironment;
private readonly IScriptBundler _scriptBundler; private readonly IScriptBundler _scriptBundler;
private readonly IStyleBundler _styleBundler; private readonly IStyleBundler _styleBundler;
private readonly IThemeManager _themeManager;
private readonly IServiceProvider _serviceProvider; private readonly IServiceProvider _serviceProvider;
private readonly IDynamicFileProvider _dynamicFileProvider;
private readonly ConcurrentDictionary<string, string> _cache; private readonly ConcurrentDictionary<string, string> _cache;
@ -32,13 +34,12 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling
IScriptBundler scriptBundler, IScriptBundler scriptBundler,
IStyleBundler styleBundler, IStyleBundler styleBundler,
IHostingEnvironment hostingEnvironment, IHostingEnvironment hostingEnvironment,
IThemeManager themeManager, IServiceProvider serviceProvider, IDynamicFileProvider dynamicFileProvider)
IServiceProvider serviceProvider)
{ {
_hostingEnvironment = hostingEnvironment; _hostingEnvironment = hostingEnvironment;
_scriptBundler = scriptBundler; _scriptBundler = scriptBundler;
_themeManager = themeManager;
_serviceProvider = serviceProvider; _serviceProvider = serviceProvider;
_dynamicFileProvider = dynamicFileProvider;
_styleBundler = styleBundler; _styleBundler = styleBundler;
_options = options.Value; _options = options.Value;
@ -82,9 +83,19 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling
protected virtual void SaveBundleResult(string bundleRelativePath, BundleResult bundleResult) protected virtual void SaveBundleResult(string bundleRelativePath, BundleResult bundleResult)
{ {
var bundleFilePath = Path.Combine(_hostingEnvironment.WebRootPath, bundleRelativePath); //TODO: Optimize?
DirectoryHelper.CreateIfNotExists(Path.GetDirectoryName(bundleFilePath)); var fileName = bundleRelativePath.Substring(bundleRelativePath.IndexOf('/') + 1);
File.WriteAllText(bundleFilePath, bundleResult.Content, Encoding.UTF8);
_dynamicFileProvider.AddOrUpdate(
new InMemoryFileInfo(
Encoding.UTF8.GetBytes(bundleResult.Content),
"/wwwroot/" + bundleRelativePath, //TODO: get rid of wwwroot!
fileName
)
);
//var bundleFilePath = Path.Combine(_hostingEnvironment.WebRootPath, bundleRelativePath);
//DirectoryHelper.CreateIfNotExists(Path.GetDirectoryName(bundleFilePath));
//File.WriteAllText(bundleFilePath, bundleResult.Content, Encoding.UTF8);
} }
public virtual void CreateStyleBundle(string bundleName, Action<BundleConfiguration> configureAction) public virtual void CreateStyleBundle(string bundleName, Action<BundleConfiguration> configureAction)

9
src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/DictionaryBasedFileProvider.cs

@ -7,7 +7,7 @@ namespace Volo.Abp.VirtualFileSystem
{ {
public abstract class DictionaryBasedFileProvider : IFileProvider public abstract class DictionaryBasedFileProvider : IFileProvider
{ {
protected abstract Dictionary<string, IFileInfo> Files { get; } protected abstract IDictionary<string, IFileInfo> Files { get; }
public virtual IFileInfo GetFileInfo(string subpath) public virtual IFileInfo GetFileInfo(string subpath)
{ {
@ -16,7 +16,7 @@ namespace Volo.Abp.VirtualFileSystem
return new NotFoundFileInfo(subpath); return new NotFoundFileInfo(subpath);
} }
var file = Files.GetOrDefault(VirtualFilePathHelper.NormalizePath(subpath)); var file = Files.GetOrDefault(NormalizePath(subpath));
if (file == null) if (file == null)
{ {
@ -60,5 +60,10 @@ namespace Volo.Abp.VirtualFileSystem
{ {
return NullChangeToken.Singleton; return NullChangeToken.Singleton;
} }
protected virtual string NormalizePath(string subpath)
{
return subpath;
}
} }
} }

31
src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/DynamicFileProvider.cs

@ -0,0 +1,31 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using Microsoft.Extensions.FileProviders;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.VirtualFileSystem
{
//TODO: Implement Watch!
//TODO: Work with dictionaries?
public class DynamicFileProvider : DictionaryBasedFileProvider, IDynamicFileProvider, ISingletonDependency
{
protected override IDictionary<string, IFileInfo> Files => DynamicFiles;
protected ConcurrentDictionary<string, IFileInfo> DynamicFiles { get; }
public DynamicFileProvider()
{
DynamicFiles = new ConcurrentDictionary<string, IFileInfo>();
}
public void AddOrUpdate(IFileInfo fileInfo)
{
DynamicFiles.AddOrUpdate(fileInfo.PhysicalPath, fileInfo, (key, value) => fileInfo);
}
public bool Delete(string filePath)
{
return DynamicFiles.TryRemove(filePath, out _);
}
}
}

36
src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/InMemoryFileInfo.cs

@ -0,0 +1,36 @@
using System;
using System.IO;
using Microsoft.Extensions.FileProviders;
namespace Volo.Abp.VirtualFileSystem
{
public class InMemoryFileInfo : IFileInfo
{
public bool Exists => true;
public long Length => _fileContent.Length;
public string PhysicalPath { get; }
public string Name { get; }
public DateTimeOffset LastModified { get; }
public bool IsDirectory => false;
private readonly byte[] _fileContent;
public InMemoryFileInfo(byte[] fileContent, string physicalPath, string name)
{
PhysicalPath = physicalPath;
Name = name;
_fileContent = fileContent;
LastModified = DateTimeOffset.Now;
}
public Stream CreateReadStream()
{
return new MemoryStream(_fileContent, false);
}
}
}

43
src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/VirtualFileProvider.cs

@ -10,53 +10,53 @@ namespace Volo.Abp.VirtualFileSystem
{ {
public class VirtualFileProvider : IVirtualFileProvider, ISingletonDependency public class VirtualFileProvider : IVirtualFileProvider, ISingletonDependency
{ {
private readonly IFileProvider _fileProvider; private readonly IFileProvider _hybridFileProvider;
private readonly VirtualFileSystemOptions _options; private readonly VirtualFileSystemOptions _options;
public VirtualFileProvider(IOptions<VirtualFileSystemOptions> options) public VirtualFileProvider(IOptions<VirtualFileSystemOptions> options, IDynamicFileProvider dynamicFileProvider)
{ {
_options = options.Value; _options = options.Value;
_fileProvider = CreateHybridProvider(); _hybridFileProvider = CreateHybridProvider(dynamicFileProvider);
} }
public virtual IFileInfo GetFileInfo(string subpath) public virtual IFileInfo GetFileInfo(string subpath)
{ {
return _fileProvider.GetFileInfo(subpath); return _hybridFileProvider.GetFileInfo(subpath);
} }
public virtual IDirectoryContents GetDirectoryContents(string subpath) public virtual IDirectoryContents GetDirectoryContents(string subpath)
{ {
return _fileProvider.GetDirectoryContents(subpath); return _hybridFileProvider.GetDirectoryContents(subpath);
} }
public virtual IChangeToken Watch(string filter) public virtual IChangeToken Watch(string filter)
{ {
return _fileProvider.Watch(filter); return _hybridFileProvider.Watch(filter);
} }
protected virtual IFileProvider CreateHybridProvider() protected virtual IFileProvider CreateHybridProvider(IDynamicFileProvider dynamicFileProvider)
{ {
IFileProvider fileProvider = new InternalVirtualFileProvider(_options); var fileProviders = new List<IFileProvider>();
fileProviders.Add(dynamicFileProvider);
if (_options.FileSets.PhysicalPaths.Any()) if (_options.FileSets.PhysicalPaths.Any())
{ {
var fileProviders = _options.FileSets.PhysicalPaths fileProviders.AddRange(
.Select(rootPath => new PhysicalFileProvider(rootPath)) _options.FileSets.PhysicalPaths
.Reverse() .Select(rootPath => new PhysicalFileProvider(rootPath))
.Cast<IFileProvider>() .Reverse()
.ToList(); );
fileProviders.Add(fileProvider);
fileProvider = new CompositeFileProvider(fileProviders);
} }
return fileProvider; fileProviders.Add(new InternalVirtualFileProvider(_options));
return new CompositeFileProvider(fileProviders);
} }
protected class InternalVirtualFileProvider : DictionaryBasedFileProvider protected class InternalVirtualFileProvider : DictionaryBasedFileProvider
{ {
protected override Dictionary<string, IFileInfo> Files => _files.Value; protected override IDictionary<string, IFileInfo> Files => _files.Value;
private readonly VirtualFileSystemOptions _options; private readonly VirtualFileSystemOptions _options;
private readonly Lazy<Dictionary<string, IFileInfo>> _files; private readonly Lazy<Dictionary<string, IFileInfo>> _files;
@ -81,6 +81,11 @@ namespace Volo.Abp.VirtualFileSystem
return files; return files;
} }
protected override string NormalizePath(string subpath)
{
return VirtualFilePathHelper.NormalizePath(subpath);
}
} }
} }
} }
Loading…
Cancel
Save