Browse Source

Merge branch 'dev' into EngincanV/blazor-extension-property

pull/16823/head
Engincan VESKE 3 years ago
parent
commit
a082bbc652
  1. 8
      docs/en/Migration-Guides/docs/en/Migration-Guides/Abp-7_4.md
  2. 2
      framework/src/Volo.Abp.TextTemplating.Core/Volo/Abp/TextTemplating/AbpTemplateRenderer.cs
  3. 3
      framework/src/Volo.Abp.TextTemplating.Core/Volo/Abp/TextTemplating/AbpTextTemplatingOptions.cs
  4. 14
      framework/src/Volo.Abp.TextTemplating.Core/Volo/Abp/TextTemplating/IDynamicTemplateDefinitionStore.cs
  5. 14
      framework/src/Volo.Abp.TextTemplating.Core/Volo/Abp/TextTemplating/IStaticTemplateDefinitionStore.cs
  6. 13
      framework/src/Volo.Abp.TextTemplating.Core/Volo/Abp/TextTemplating/ITemplateDefinitionManager.cs
  7. 29
      framework/src/Volo.Abp.TextTemplating.Core/Volo/Abp/TextTemplating/NullIDynamicTemplateDefinitionStore.cs
  8. 83
      framework/src/Volo.Abp.TextTemplating.Core/Volo/Abp/TextTemplating/StaticTemplateDefinitionStore.cs
  9. 6
      framework/src/Volo.Abp.TextTemplating.Core/Volo/Abp/TextTemplating/TemplateContentProvider.cs
  10. 18
      framework/src/Volo.Abp.TextTemplating.Core/Volo/Abp/TextTemplating/TemplateDefinition.cs
  11. 81
      framework/src/Volo.Abp.TextTemplating.Core/Volo/Abp/TextTemplating/TemplateDefinitionManager.cs
  12. 4
      framework/src/Volo.Abp.TextTemplating.Core/Volo/Abp/TextTemplating/TemplateRenderingEngineBase.cs
  13. 11
      framework/src/Volo.Abp.TextTemplating.Core/Volo/Abp/TextTemplating/VirtualFiles/FileInfoLocalizedTemplateContentReader.cs
  14. 8
      framework/src/Volo.Abp.TextTemplating.Core/Volo/Abp/TextTemplating/VirtualFiles/TemplateContentFileInfo.cs
  15. 56
      framework/src/Volo.Abp.TextTemplating.Core/Volo/Abp/TextTemplating/VirtualFiles/TemplateContentFileProvider.cs
  16. 18
      framework/src/Volo.Abp.TextTemplating.Core/Volo/Abp/TextTemplating/VirtualFiles/VirtualFolderLocalizedTemplateContentReader.cs
  17. 5
      framework/src/Volo.Abp.TextTemplating.Razor/Volo/Abp/TextTemplating/Razor/DefaultAbpCompiledViewProvider.cs
  18. 2
      framework/src/Volo.Abp.TextTemplating.Razor/Volo/Abp/TextTemplating/Razor/RazorTemplateRenderingEngine.cs
  19. 2
      framework/src/Volo.Abp.TextTemplating.Scriban/Volo/Abp/TextTemplating/Scriban/ScribanTemplateRenderingEngine.cs
  20. 2
      framework/test/Volo.Abp.TextTemplating.Razor.Tests/Volo/Abp/TextTemplating/Razor/AbpCompiledViewProviderOptions_Tests.cs
  21. 19
      framework/test/Volo.Abp.TextTemplating.Razor.Tests/Volo/Abp/TextTemplating/Razor/RazorTemplateContentFileProvider_Tests.cs
  22. 19
      framework/test/Volo.Abp.TextTemplating.Scriban.Tests/Volo/Abp/TextTemplating/Scriban/SampleTemplates/ScribanTemplateContentFileProvider_Tests.cs
  23. 17
      framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/TemplateDefinitionTests.cs
  24. 2
      framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/VirtualFiles/LocalizedTemplateContentReaderFactory_Tests.cs
  25. 29
      framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/VirtualFiles/TemplateContentFileProvider_Tests.cs
  26. 6
      framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor_Tests.cs
  27. 4
      modules/openiddict/src/Volo.Abp.OpenIddict.Domain/Volo/Abp/OpenIddict/Applications/AbpApplicationManager.cs
  28. 50
      modules/openiddict/test/Volo.Abp.OpenIddict.Domain.Tests/Volo/Abp/OpenIddict/Applications/AbpApplicationManager_Tests.cs
  29. 13
      modules/openiddict/test/Volo.Abp.OpenIddict.TestBase/Volo/Abp/OpenIddict/OpenIddictDataSeedContributor.cs
  30. 2
      templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Data/MyProjectNameEFCoreDbSchemaMigrator.cs
  31. 2
      templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Data/MyProjectNameEFCoreDbSchemaMigrator.cs
  32. 2
      templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Data/MyProjectNameEFCoreDbSchemaMigrator.cs
  33. 2
      templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Data/MyProjectNameEFCoreDbSchemaMigrator.cs
  34. 2
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/EntityFrameworkCore/EntityFrameworkCoreMyProjectNameDbSchemaMigrator.cs

8
docs/en/Migration-Guides/docs/en/Migration-Guides/Abp-7_4.md

@ -0,0 +1,8 @@
# ABP Version 7.4 Migration Guide
This document is a guide for upgrading ABP v7.3 solutions to ABP v7.4. There are a few changes in this version that may affect your applications, please read it carefully and apply the necessary changes to your application.
## TemplateDefinition
The `LocalizationResource(Type)` of `TemplateDefinition` class is changed to `LocalizationResourceName(string)`.

2
framework/src/Volo.Abp.TextTemplating.Core/Volo/Abp/TextTemplating/AbpTemplateRenderer.cs

@ -29,7 +29,7 @@ public class AbpTemplateRenderer : ITemplateRenderer, ITransientDependency
string cultureName = null, string cultureName = null,
Dictionary<string, object> globalContext = null) Dictionary<string, object> globalContext = null)
{ {
var templateDefinition = TemplateDefinitionManager.Get(templateName); var templateDefinition = await TemplateDefinitionManager.GetAsync(templateName);
var renderEngine = templateDefinition.RenderEngine; var renderEngine = templateDefinition.RenderEngine;

3
framework/src/Volo.Abp.TextTemplating.Core/Volo/Abp/TextTemplating/AbpTextTemplatingOptions.cs

@ -12,10 +12,13 @@ public class AbpTextTemplatingOptions
public string DefaultRenderingEngine { get; set; } public string DefaultRenderingEngine { get; set; }
public HashSet<string> DeletedTemplates { get; }
public AbpTextTemplatingOptions() public AbpTextTemplatingOptions()
{ {
DefinitionProviders = new TypeList<ITemplateDefinitionProvider>(); DefinitionProviders = new TypeList<ITemplateDefinitionProvider>();
ContentContributors = new TypeList<ITemplateContentContributor>(); ContentContributors = new TypeList<ITemplateContentContributor>();
RenderingEngines = new Dictionary<string, Type>(); RenderingEngines = new Dictionary<string, Type>();
DeletedTemplates = new HashSet<string>();
} }
} }

14
framework/src/Volo.Abp.TextTemplating.Core/Volo/Abp/TextTemplating/IDynamicTemplateDefinitionStore.cs

@ -0,0 +1,14 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using JetBrains.Annotations;
namespace Volo.Abp.TextTemplating;
public interface IDynamicTemplateDefinitionStore
{
Task<TemplateDefinition> GetAsync([NotNull] string name);
Task<IReadOnlyList<TemplateDefinition>> GetAllAsync();
Task<TemplateDefinition> GetOrNullAsync(string name);
}

14
framework/src/Volo.Abp.TextTemplating.Core/Volo/Abp/TextTemplating/IStaticTemplateDefinitionStore.cs

@ -0,0 +1,14 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using JetBrains.Annotations;
namespace Volo.Abp.TextTemplating;
public interface IStaticTemplateDefinitionStore
{
Task<TemplateDefinition> GetAsync([NotNull] string name);
Task<IReadOnlyList<TemplateDefinition>> GetAllAsync();
Task<TemplateDefinition> GetOrNullAsync(string name);
}

13
framework/src/Volo.Abp.TextTemplating.Core/Volo/Abp/TextTemplating/ITemplateDefinitionManager.cs

@ -1,16 +1,17 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks;
using JetBrains.Annotations; using JetBrains.Annotations;
namespace Volo.Abp.TextTemplating; namespace Volo.Abp.TextTemplating;
public interface ITemplateDefinitionManager public interface ITemplateDefinitionManager
{ {
[NotNull] [ItemNotNull]
TemplateDefinition Get([NotNull] string name); Task<TemplateDefinition> GetAsync([NotNull] string name);
[NotNull] [ItemNotNull]
IReadOnlyList<TemplateDefinition> GetAll(); Task<IReadOnlyList<TemplateDefinition>> GetAllAsync();
[CanBeNull] [ItemCanBeNull]
TemplateDefinition GetOrNull(string name); Task<TemplateDefinition> GetOrNullAsync(string name);
} }

29
framework/src/Volo.Abp.TextTemplating.Core/Volo/Abp/TextTemplating/NullIDynamicTemplateDefinitionStore.cs

@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.TextTemplating;
public class NullIDynamicTemplateDefinitionStore : IDynamicTemplateDefinitionStore, ISingletonDependency
{
private readonly static Task<TemplateDefinition> CachedTemplateResult = Task.FromResult((TemplateDefinition)null);
private readonly static Task<IReadOnlyList<TemplateDefinition>> CachedFeaturesResult = Task.FromResult((IReadOnlyList<TemplateDefinition>)Array.Empty<TemplateDefinition>().ToImmutableList());
public Task<TemplateDefinition> GetAsync(string name)
{
return CachedTemplateResult;
}
public Task<IReadOnlyList<TemplateDefinition>> GetAllAsync()
{
return CachedFeaturesResult;
}
public Task<TemplateDefinition> GetOrNullAsync(string name)
{
return CachedTemplateResult;
}
}

83
framework/src/Volo.Abp.TextTemplating.Core/Volo/Abp/TextTemplating/StaticTemplateDefinitionStore.cs

@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.TextTemplating;
public class StaticTemplateDefinitionStore : IStaticTemplateDefinitionStore, ISingletonDependency
{
protected Lazy<IDictionary<string, TemplateDefinition>> TemplateDefinitions { get; }
protected AbpTextTemplatingOptions Options { get; }
protected IServiceProvider ServiceProvider { get; }
public StaticTemplateDefinitionStore(IOptions<AbpTextTemplatingOptions> options, IServiceProvider serviceProvider)
{
ServiceProvider = serviceProvider;
Options = options.Value;
TemplateDefinitions = new Lazy<IDictionary<string, TemplateDefinition>>(CreateTextTemplateDefinitions, true);
}
public virtual Task<TemplateDefinition> GetAsync(string name)
{
Check.NotNull(name, nameof(name));
var template = GetOrNullAsync(name);
if (template == null)
{
throw new AbpException("Undefined template: " + name);
}
return template;
}
public virtual Task<IReadOnlyList<TemplateDefinition>> GetAllAsync()
{
return Task.FromResult<IReadOnlyList<TemplateDefinition>>(TemplateDefinitions.Value.Values.ToImmutableList());
}
public virtual Task<TemplateDefinition> GetOrNullAsync(string name)
{
return Task.FromResult(TemplateDefinitions.Value.GetOrDefault(name));
}
protected virtual IDictionary<string, TemplateDefinition> CreateTextTemplateDefinitions()
{
var templates = new Dictionary<string, TemplateDefinition>();
using (var scope = ServiceProvider.CreateScope())
{
var providers = Options
.DefinitionProviders
.Select(p => scope.ServiceProvider.GetRequiredService(p) as ITemplateDefinitionProvider)
.ToList();
var context = new TemplateDefinitionContext(templates);
foreach (var provider in providers)
{
provider.PreDefine(context);
}
foreach (var provider in providers)
{
provider.Define(context);
}
foreach (var provider in providers)
{
provider.PostDefine(context);
}
}
return templates;
}
}

6
framework/src/Volo.Abp.TextTemplating.Core/Volo/Abp/TextTemplating/TemplateContentProvider.cs

@ -26,14 +26,14 @@ public class TemplateContentProvider : ITemplateContentProvider, ITransientDepen
_templateDefinitionManager = templateDefinitionManager; _templateDefinitionManager = templateDefinitionManager;
} }
public virtual Task<string> GetContentOrNullAsync( public virtual async Task<string> GetContentOrNullAsync(
[NotNull] string templateName, [NotNull] string templateName,
[CanBeNull] string cultureName = null, [CanBeNull] string cultureName = null,
bool tryDefaults = true, bool tryDefaults = true,
bool useCurrentCultureIfCultureNameIsNull = true) bool useCurrentCultureIfCultureNameIsNull = true)
{ {
var template = _templateDefinitionManager.Get(templateName); var template = await _templateDefinitionManager.GetAsync(templateName);
return GetContentOrNullAsync(template, cultureName); return await GetContentOrNullAsync(template, cultureName);
} }
public virtual async Task<string> GetContentOrNullAsync( public virtual async Task<string> GetContentOrNullAsync(

18
framework/src/Volo.Abp.TextTemplating.Core/Volo/Abp/TextTemplating/TemplateDefinition.cs

@ -28,7 +28,7 @@ public class TemplateDefinition : IHasNameWithLocalizableDisplayName
public string Layout { get; set; } public string Layout { get; set; }
[CanBeNull] [CanBeNull]
public Type LocalizationResource { get; set; } public string LocalizationResourceName { get; set; }
public bool IsInlineLocalized { get; set; } public bool IsInlineLocalized { get; set; }
@ -60,14 +60,26 @@ public class TemplateDefinition : IHasNameWithLocalizableDisplayName
public TemplateDefinition( public TemplateDefinition(
[NotNull] string name, [NotNull] string name,
[CanBeNull] Type localizationResource = null, [NotNull] Type localizationResource,
[CanBeNull] ILocalizableString displayName = null,
bool isLayout = false,
string layout = null,
string defaultCultureName = null)
: this(name, LocalizationResourceNameAttribute.GetName(localizationResource), displayName, isLayout, layout, defaultCultureName)
{
}
public TemplateDefinition(
[NotNull] string name,
[CanBeNull] string localizationResourceName = null,
[CanBeNull] ILocalizableString displayName = null, [CanBeNull] ILocalizableString displayName = null,
bool isLayout = false, bool isLayout = false,
string layout = null, string layout = null,
string defaultCultureName = null) string defaultCultureName = null)
{ {
Name = Check.NotNullOrWhiteSpace(name, nameof(name), MaxNameLength); Name = Check.NotNullOrWhiteSpace(name, nameof(name), MaxNameLength);
LocalizationResource = localizationResource; LocalizationResourceName = localizationResourceName;
DisplayName = displayName ?? new FixedLocalizableString(Name); DisplayName = displayName ?? new FixedLocalizableString(Name);
IsLayout = isLayout; IsLayout = isLayout;
Layout = layout; Layout = layout;

81
framework/src/Volo.Abp.TextTemplating.Core/Volo/Abp/TextTemplating/TemplateDefinitionManager.cs

@ -1,85 +1,50 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Linq; using System.Linq;
using Microsoft.Extensions.DependencyInjection; using System.Threading.Tasks;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
namespace Volo.Abp.TextTemplating; namespace Volo.Abp.TextTemplating;
public class TemplateDefinitionManager : ITemplateDefinitionManager, ISingletonDependency public class TemplateDefinitionManager : ITemplateDefinitionManager, ISingletonDependency
{ {
protected Lazy<IDictionary<string, TemplateDefinition>> TemplateDefinitions { get; } protected readonly IStaticTemplateDefinitionStore StaticStore;
protected readonly IDynamicTemplateDefinitionStore DynamicStore;
protected AbpTextTemplatingOptions Options { get; } public TemplateDefinitionManager(IStaticTemplateDefinitionStore staticStore, IDynamicTemplateDefinitionStore dynamicStore)
protected IServiceProvider ServiceProvider { get; }
public TemplateDefinitionManager(
IOptions<AbpTextTemplatingOptions> options,
IServiceProvider serviceProvider)
{ {
ServiceProvider = serviceProvider; StaticStore = staticStore;
Options = options.Value; DynamicStore = dynamicStore;
TemplateDefinitions =
new Lazy<IDictionary<string, TemplateDefinition>>(CreateTextTemplateDefinitions, true);
} }
public virtual TemplateDefinition Get(string name) public virtual async Task<TemplateDefinition> GetAsync(string name)
{ {
Check.NotNull(name, nameof(name)); var permission = await GetOrNullAsync(name);
if (permission == null)
var template = GetOrNull(name);
if (template == null)
{ {
throw new AbpException("Undefined template: " + name); throw new AbpException("Undefined Template: " + name);
} }
return template; return permission;
} }
public virtual IReadOnlyList<TemplateDefinition> GetAll() public virtual async Task<TemplateDefinition> GetOrNullAsync(string name)
{ {
return TemplateDefinitions.Value.Values.ToImmutableList(); Check.NotNull(name, nameof(name));
}
public virtual TemplateDefinition GetOrNull(string name) return await StaticStore.GetOrNullAsync(name) ?? await DynamicStore.GetOrNullAsync(name);
{
return TemplateDefinitions.Value.GetOrDefault(name);
} }
protected virtual IDictionary<string, TemplateDefinition> CreateTextTemplateDefinitions() public virtual async Task<IReadOnlyList<TemplateDefinition>> GetAllAsync()
{ {
var templates = new Dictionary<string, TemplateDefinition>(); var staticTemplates = await StaticStore.GetAllAsync();
var staticTemplateNames = staticTemplates
using (var scope = ServiceProvider.CreateScope()) .Select(p => p.Name)
{ .ToImmutableHashSet();
var providers = Options
.DefinitionProviders
.Select(p => scope.ServiceProvider.GetRequiredService(p) as ITemplateDefinitionProvider)
.ToList();
var context = new TemplateDefinitionContext(templates);
foreach (var provider in providers) var dynamicTemplates = await DynamicStore.GetAllAsync();
{
provider.PreDefine(context);
}
foreach (var provider in providers)
{
provider.Define(context);
}
foreach (var provider in providers)
{
provider.PostDefine(context);
}
}
return templates; /* We prefer static Templates over dynamics */
return staticTemplates.Concat(dynamicTemplates.Where(d => !staticTemplateNames.Contains(d.Name))).ToImmutableList();
} }
} }

4
framework/src/Volo.Abp.TextTemplating.Core/Volo/Abp/TextTemplating/TemplateRenderingEngineBase.cs

@ -31,9 +31,9 @@ public abstract class TemplateRenderingEngineBase : ITemplateRenderingEngine
protected virtual IStringLocalizer GetLocalizerOrNull(TemplateDefinition templateDefinition) protected virtual IStringLocalizer GetLocalizerOrNull(TemplateDefinition templateDefinition)
{ {
if (templateDefinition.LocalizationResource != null) if (templateDefinition.LocalizationResourceName != null)
{ {
return StringLocalizerFactory.Create(templateDefinition.LocalizationResource); return StringLocalizerFactory.CreateByResourceName(templateDefinition.LocalizationResourceName);
} }
return StringLocalizerFactory.CreateDefaultOrNull(); return StringLocalizerFactory.CreateDefaultOrNull();

11
framework/src/Volo.Abp.TextTemplating.Core/Volo/Abp/TextTemplating/VirtualFiles/FileInfoLocalizedTemplateContentReader.cs

@ -5,10 +5,12 @@ namespace Volo.Abp.TextTemplating.VirtualFiles;
public class FileInfoLocalizedTemplateContentReader : ILocalizedTemplateContentReader public class FileInfoLocalizedTemplateContentReader : ILocalizedTemplateContentReader
{ {
private IFileInfo _fileInfo;
private string _content; private string _content;
public async Task ReadContentsAsync(IFileInfo fileInfo) public async Task ReadContentsAsync(IFileInfo fileInfo)
{ {
_fileInfo = fileInfo;
_content = await fileInfo.ReadAsStringAsync(); _content = await fileInfo.ReadAsStringAsync();
} }
@ -21,4 +23,13 @@ public class FileInfoLocalizedTemplateContentReader : ILocalizedTemplateContentR
return null; return null;
} }
public TemplateContentFileInfo GetFile()
{
return new TemplateContentFileInfo()
{
FileName = _fileInfo.Name,
FileContent = _content
};
}
} }

8
framework/src/Volo.Abp.TextTemplating.Core/Volo/Abp/TextTemplating/VirtualFiles/TemplateContentFileInfo.cs

@ -0,0 +1,8 @@
namespace Volo.Abp.TextTemplating.VirtualFiles;
public class TemplateContentFileInfo
{
public string FileName { get; set; }
public string FileContent { get; set; }
}

56
framework/src/Volo.Abp.TextTemplating.Core/Volo/Abp/TextTemplating/VirtualFiles/TemplateContentFileProvider.cs

@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.VirtualFileSystem;
namespace Volo.Abp.TextTemplating.VirtualFiles;
public class TemplateContentFileProvider : ITransientDependency
{
protected IVirtualFileProvider VirtualFileProvider { get; }
public TemplateContentFileProvider(IVirtualFileProvider virtualFileProvider)
{
VirtualFileProvider = virtualFileProvider;
}
public async Task<List<TemplateContentFileInfo>> GetFilesAsync(TemplateDefinition templateDefinition)
{
var files = new List<TemplateContentFileInfo>();
var virtualPath = templateDefinition.GetVirtualFilePathOrNull();
if (virtualPath == null)
{
return files;
}
var fileInfo = VirtualFileProvider.GetFileInfo(virtualPath);
if (!fileInfo.Exists)
{
var directoryContents = VirtualFileProvider.GetDirectoryContents(virtualPath);
if (!directoryContents.Exists)
{
throw new AbpException("Could not find a file/folder at the location: " + virtualPath);
}
fileInfo = new VirtualDirectoryFileInfo(virtualPath, virtualPath, DateTimeOffset.UtcNow);
}
if (fileInfo.IsDirectory)
{
//TODO: Configure file extensions.
var folderReader = new VirtualFolderLocalizedTemplateContentReader(new[] { ".tpl", ".cshtml" });
await folderReader.ReadContentsAsync(VirtualFileProvider, virtualPath);
files.AddRange(folderReader.GetFiles());
}
else
{
var singleFileReader = new FileInfoLocalizedTemplateContentReader();
await singleFileReader.ReadContentsAsync(fileInfo);
files.Add(singleFileReader.GetFile());
}
return files;
}
}

18
framework/src/Volo.Abp.TextTemplating.Core/Volo/Abp/TextTemplating/VirtualFiles/VirtualFolderLocalizedTemplateContentReader.cs

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.FileProviders;
using Volo.Abp.VirtualFileSystem; using Volo.Abp.VirtualFileSystem;
@ -8,7 +9,7 @@ namespace Volo.Abp.TextTemplating.VirtualFiles;
public class VirtualFolderLocalizedTemplateContentReader : ILocalizedTemplateContentReader public class VirtualFolderLocalizedTemplateContentReader : ILocalizedTemplateContentReader
{ {
private Dictionary<string, string> _dictionary; private Dictionary<string, TemplateContentFileInfo> _dictionary;
private readonly string[] _fileExtension; private readonly string[] _fileExtension;
public VirtualFolderLocalizedTemplateContentReader(string[] fileExtension) public VirtualFolderLocalizedTemplateContentReader(string[] fileExtension)
@ -20,7 +21,7 @@ public class VirtualFolderLocalizedTemplateContentReader : ILocalizedTemplateCon
IVirtualFileProvider virtualFileProvider, IVirtualFileProvider virtualFileProvider,
string virtualPath) string virtualPath)
{ {
_dictionary = new Dictionary<string, string>(); _dictionary = new Dictionary<string, TemplateContentFileInfo>();
var directoryContents = virtualFileProvider.GetDirectoryContents(virtualPath); var directoryContents = virtualFileProvider.GetDirectoryContents(virtualPath);
if (!directoryContents.Exists) if (!directoryContents.Exists)
@ -35,7 +36,11 @@ public class VirtualFolderLocalizedTemplateContentReader : ILocalizedTemplateCon
continue; continue;
} }
_dictionary.Add(file.Name.RemovePostFix(_fileExtension), await file.ReadAsStringAsync()); _dictionary.Add(file.Name.RemovePostFix(_fileExtension), new TemplateContentFileInfo()
{
FileName = file.Name,
FileContent = await file.ReadAsStringAsync()
});
} }
} }
@ -46,6 +51,11 @@ public class VirtualFolderLocalizedTemplateContentReader : ILocalizedTemplateCon
return null; return null;
} }
return _dictionary.GetOrDefault(cultureName); return _dictionary.GetOrDefault(cultureName)?.FileContent;
}
public List<TemplateContentFileInfo> GetFiles()
{
return _dictionary.Values.ToList();
} }
} }

5
framework/src/Volo.Abp.TextTemplating.Razor/Volo/Abp/TextTemplating/Razor/DefaultAbpCompiledViewProvider.cs

@ -45,6 +45,11 @@ public class DefaultAbpCompiledViewProvider : IAbpCompiledViewProvider, ITransie
} }
var templateContent = await _templateContentProvider.GetContentOrNullAsync(templateDefinition); var templateContent = await _templateContentProvider.GetContentOrNullAsync(templateDefinition);
if (templateContent == null)
{
throw new AbpException($"Razor template content of {templateDefinition.Name} is null!");
}
return CachedAssembles.GetOrAdd((templateDefinition.Name + templateContent).ToMd5(), await CreateAssembly(templateContent)); return CachedAssembles.GetOrAdd((templateDefinition.Name + templateContent).ToMd5(), await CreateAssembly(templateContent));
} }

2
framework/src/Volo.Abp.TextTemplating.Razor/Volo/Abp/TextTemplating/Razor/RazorTemplateRenderingEngine.cs

@ -74,7 +74,7 @@ public class RazorTemplateRenderingEngine : TemplateRenderingEngineBase, ITransi
Dictionary<string, object> globalContext, Dictionary<string, object> globalContext,
object model = null) object model = null)
{ {
var templateDefinition = TemplateDefinitionManager.Get(templateName); var templateDefinition = await TemplateDefinitionManager.GetAsync(templateName);
var renderedContent = await RenderSingleTemplateAsync( var renderedContent = await RenderSingleTemplateAsync(
templateDefinition, templateDefinition,

2
framework/src/Volo.Abp.TextTemplating.Scriban/Volo/Abp/TextTemplating/Scriban/ScribanTemplateRenderingEngine.cs

@ -61,7 +61,7 @@ public class ScribanTemplateRenderingEngine : TemplateRenderingEngineBase, ITran
Dictionary<string, object> globalContext, Dictionary<string, object> globalContext,
object model = null) object model = null)
{ {
var templateDefinition = TemplateDefinitionManager.Get(templateName); var templateDefinition = await TemplateDefinitionManager.GetAsync(templateName);
var renderedContent = await RenderSingleTemplateAsync( var renderedContent = await RenderSingleTemplateAsync(
templateDefinition, templateDefinition,

2
framework/test/Volo.Abp.TextTemplating.Razor.Tests/Volo/Abp/TextTemplating/Razor/AbpCompiledViewProviderOptions_Tests.cs

@ -38,7 +38,7 @@ public class AbpCompiledViewProviderOptions_Tests : TemplateDefinitionTests<Razo
[Fact] [Fact]
public async Task Custom_TemplateReferences_Test() public async Task Custom_TemplateReferences_Test()
{ {
var templateDefinition = _templateDefinitionManager.GetOrNull(RazorTestTemplates.TestTemplate); var templateDefinition = await _templateDefinitionManager.GetOrNullAsync(RazorTestTemplates.TestTemplate);
var assembly = await _compiledViewProvider.GetAssemblyAsync(templateDefinition); var assembly = await _compiledViewProvider.GetAssemblyAsync(templateDefinition);

19
framework/test/Volo.Abp.TextTemplating.Razor.Tests/Volo/Abp/TextTemplating/Razor/RazorTemplateContentFileProvider_Tests.cs

@ -0,0 +1,19 @@
using System.Threading.Tasks;
using Shouldly;
using Volo.Abp.TextTemplating.VirtualFiles;
using Xunit;
namespace Volo.Abp.TextTemplating.Razor;
public class RazorTemplateContentFileProvider_Tests : TemplateContentFileProvider_Tests<RazorTextTemplatingTestModule>
{
[Fact]
public async Task GetRazorFilesAsync()
{
var definition = await TemplateDefinitionManager.GetAsync(TestTemplates.WelcomeEmail);
var files = await TemplateContentFileProvider.GetFilesAsync(definition);
files.Count.ShouldBe(2);
files.ShouldContain(x => x.FileName == "en.cshtml" && x.FileContent.Contains("Welcome @Model.Name to the abp.io!"));
files.ShouldContain(x => x.FileName == "tr.cshtml" && x.FileContent.Contains("Merhaba @Model.Name, abp.io'ya hoşgeldiniz!"));
}
}

19
framework/test/Volo.Abp.TextTemplating.Scriban.Tests/Volo/Abp/TextTemplating/Scriban/SampleTemplates/ScribanTemplateContentFileProvider_Tests.cs

@ -0,0 +1,19 @@
using System.Threading.Tasks;
using Shouldly;
using Volo.Abp.TextTemplating.VirtualFiles;
using Xunit;
namespace Volo.Abp.TextTemplating.Scriban.SampleTemplates;
public class ScribanTemplateContentFileProvider_Tests : TemplateContentFileProvider_Tests<ScribanTextTemplatingTestModule>
{
[Fact]
public async Task GetScribanFilesAsync()
{
var definition = await TemplateDefinitionManager.GetAsync(TestTemplates.WelcomeEmail);
var files = await TemplateContentFileProvider.GetFilesAsync(definition);
files.Count.ShouldBe(2);
files.ShouldContain(x => x.FileName == "en.tpl" && x.FileContent.Contains("Welcome {{model.name}} to the abp.io!"));
files.ShouldContain(x => x.FileName == "tr.tpl" && x.FileContent.Contains("Merhaba {{model.name}}, abp.io'ya hoşgeldiniz!"));
}
}

17
framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/TemplateDefinitionTests.cs

@ -1,4 +1,5 @@
using Shouldly; using System.Threading.Tasks;
using Shouldly;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Xunit; using Xunit;
@ -15,28 +16,28 @@ public abstract class TemplateDefinitionTests<TStartupModule> : AbpTextTemplatin
} }
[Fact] [Fact]
public void Should_Retrieve_Template_Definition_By_Name() public async Task Should_Retrieve_Template_Definition_By_Name()
{ {
var welcomeEmailTemplate = TemplateDefinitionManager.Get(TestTemplates.WelcomeEmail); var welcomeEmailTemplate = await TemplateDefinitionManager.GetAsync(TestTemplates.WelcomeEmail);
welcomeEmailTemplate.Name.ShouldBe(TestTemplates.WelcomeEmail); welcomeEmailTemplate.Name.ShouldBe(TestTemplates.WelcomeEmail);
welcomeEmailTemplate.IsInlineLocalized.ShouldBeFalse(); welcomeEmailTemplate.IsInlineLocalized.ShouldBeFalse();
var forgotPasswordEmailTemplate = TemplateDefinitionManager.Get(TestTemplates.ForgotPasswordEmail); var forgotPasswordEmailTemplate = await TemplateDefinitionManager.GetAsync(TestTemplates.ForgotPasswordEmail);
forgotPasswordEmailTemplate.Name.ShouldBe(TestTemplates.ForgotPasswordEmail); forgotPasswordEmailTemplate.Name.ShouldBe(TestTemplates.ForgotPasswordEmail);
forgotPasswordEmailTemplate.IsInlineLocalized.ShouldBeTrue(); forgotPasswordEmailTemplate.IsInlineLocalized.ShouldBeTrue();
} }
[Fact] [Fact]
public void Should_Get_Null_If_Template_Not_Found() public async Task Should_Get_Null_If_Template_Not_Found()
{ {
var definition = TemplateDefinitionManager.GetOrNull("undefined-template"); var definition = await TemplateDefinitionManager.GetOrNullAsync("undefined-template");
definition.ShouldBeNull(); definition.ShouldBeNull();
} }
[Fact] [Fact]
public void Should_Retrieve_All_Template_Definitions() public async Task Should_Retrieve_All_Template_Definitions()
{ {
var definitions = TemplateDefinitionManager.GetAll(); var definitions = await TemplateDefinitionManager.GetAllAsync();
definitions.Count.ShouldBeGreaterThan(1); definitions.Count.ShouldBeGreaterThan(1);
} }
} }

2
framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/VirtualFiles/LocalizedTemplateContentReaderFactory_Tests.cs

@ -24,7 +24,7 @@ public abstract class LocalizedTemplateContentReaderFactory_Tests<TStartupModule
[Fact] [Fact]
public async Task Create_Should_Work_With_PhysicalFileProvider() public async Task Create_Should_Work_With_PhysicalFileProvider()
{ {
var reader = await LocalizedTemplateContentReaderFactory.CreateAsync(TemplateDefinitionManager.Get(TestTemplates.WelcomeEmail)); var reader = await LocalizedTemplateContentReaderFactory.CreateAsync(await TemplateDefinitionManager.GetAsync(TestTemplates.WelcomeEmail));
reader.GetContentOrNull("en").ShouldBe(WelcomeEmailEnglishContent); reader.GetContentOrNull("en").ShouldBe(WelcomeEmailEnglishContent);
reader.GetContentOrNull("tr").ShouldBe(WelcomeEmailTurkishContent); reader.GetContentOrNull("tr").ShouldBe(WelcomeEmailTurkishContent);

29
framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/VirtualFiles/TemplateContentFileProvider_Tests.cs

@ -0,0 +1,29 @@
using System.Threading.Tasks;
using Shouldly;
using Volo.Abp.Modularity;
using Xunit;
namespace Volo.Abp.TextTemplating.VirtualFiles;
public abstract class TemplateContentFileProvider_Tests<TStartupModule> : AbpTextTemplatingTestBase<TStartupModule>
where TStartupModule : IAbpModule
{
protected readonly TemplateContentFileProvider TemplateContentFileProvider;
protected readonly ITemplateDefinitionManager TemplateDefinitionManager;
protected TemplateContentFileProvider_Tests()
{
TemplateContentFileProvider = GetRequiredService<TemplateContentFileProvider>();
TemplateDefinitionManager = GetRequiredService<ITemplateDefinitionManager>();
}
[Fact]
public async Task GetFilesAsync()
{
var definition = await TemplateDefinitionManager.GetAsync(TestTemplates.HybridTemplateScriban);
var files = await TemplateContentFileProvider.GetFilesAsync(definition);
files.Count.ShouldBe(1);
files.ShouldContain(x => x.FileName == "TestScribanTemplate.tpl" && x.FileContent == "Hello {{model.name}}, {{L \"HowAreYou\" }}");
}
}

6
framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor_Tests.cs

@ -24,13 +24,13 @@ public abstract class VirtualFileTemplateContributor_Tests<TStartupModule> : Abp
public async Task Should_Get_Localized_Content_By_Culture() public async Task Should_Get_Localized_Content_By_Culture()
{ {
(await VirtualFileTemplateContentContributor.GetOrNullAsync( (await VirtualFileTemplateContentContributor.GetOrNullAsync(
new TemplateContentContributorContext(TemplateDefinitionManager.Get(TestTemplates.WelcomeEmail), new TemplateContentContributorContext(await TemplateDefinitionManager.GetAsync(TestTemplates.WelcomeEmail),
ServiceProvider, ServiceProvider,
"en"))) "en")))
.ShouldBe(WelcomeEmailEnglishContent); .ShouldBe(WelcomeEmailEnglishContent);
(await VirtualFileTemplateContentContributor.GetOrNullAsync( (await VirtualFileTemplateContentContributor.GetOrNullAsync(
new TemplateContentContributorContext(TemplateDefinitionManager.Get(TestTemplates.WelcomeEmail), new TemplateContentContributorContext(await TemplateDefinitionManager.GetAsync(TestTemplates.WelcomeEmail),
ServiceProvider, ServiceProvider,
"tr"))) "tr")))
.ShouldBe(WelcomeEmailTurkishContent); .ShouldBe(WelcomeEmailTurkishContent);
@ -41,7 +41,7 @@ public abstract class VirtualFileTemplateContributor_Tests<TStartupModule> : Abp
{ {
(await VirtualFileTemplateContentContributor.GetOrNullAsync( (await VirtualFileTemplateContentContributor.GetOrNullAsync(
new TemplateContentContributorContext( new TemplateContentContributorContext(
TemplateDefinitionManager.Get(TestTemplates.ForgotPasswordEmail), await TemplateDefinitionManager.GetAsync(TestTemplates.ForgotPasswordEmail),
ServiceProvider, ServiceProvider,
null))) null)))
.ShouldBe(ForgotPasswordEmailEnglishContent); .ShouldBe(ForgotPasswordEmailEnglishContent);

4
modules/openiddict/src/Volo.Abp.OpenIddict.Domain/Volo/Abp/OpenIddict/Applications/AbpApplicationManager.cs

@ -44,8 +44,8 @@ public class AbpApplicationManager : OpenIddictApplicationManager<OpenIddictAppl
if (descriptor is AbpApplicationDescriptor model) if (descriptor is AbpApplicationDescriptor model)
{ {
application.ClientUri = model.ClientUri; model.ClientUri = application.ClientUri;
application.LogoUri = model.LogoUri; model.LogoUri = application.LogoUri;
} }
} }

50
modules/openiddict/test/Volo.Abp.OpenIddict.Domain.Tests/Volo/Abp/OpenIddict/Applications/AbpApplicationManager_Tests.cs

@ -0,0 +1,50 @@
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Shouldly;
using Xunit;
namespace Volo.Abp.OpenIddict.Applications;
public class AbpApplicationManager_Tests : OpenIddictDomainTestBase
{
private readonly IAbpApplicationManager _applicationManager;
private readonly AbpOpenIddictTestData _testData;
public AbpApplicationManager_Tests()
{
_applicationManager = ServiceProvider.GetRequiredService<IAbpApplicationManager>();
_testData = ServiceProvider.GetRequiredService<AbpOpenIddictTestData>();
}
[Fact]
public async Task Populate_Descriptor_With_Application_Test()
{
var app1 = (await _applicationManager.FindByClientIdAsync(_testData.App1ClientId)).As<OpenIddictApplicationModel>();
var descriptor = new AbpApplicationDescriptor();
await _applicationManager.PopulateAsync(descriptor, app1);
app1.ClientUri.ShouldNotBeNull();
app1.LogoUri.ShouldNotBeNull();
descriptor.ClientUri.ShouldBe(app1.ClientUri);
descriptor.LogoUri.ShouldBe(app1.LogoUri);
}
[Fact]
public async Task Populate_Application_With_Descriptor_Test()
{
var app1 = (await _applicationManager.FindByClientIdAsync(_testData.App1ClientId)).As<OpenIddictApplicationModel>();
var descriptor = new AbpApplicationDescriptor()
{
ClientUri = "https://new.com",
LogoUri = "https://new.com/logo.png"
};
await _applicationManager.PopulateAsync(app1, descriptor);
app1.ClientUri.ShouldBe(descriptor.ClientUri);
app1.LogoUri.ShouldBe(descriptor.LogoUri);
}
}

13
modules/openiddict/test/Volo.Abp.OpenIddict.TestBase/Volo/Abp/OpenIddict/OpenIddictDataSeedContributor.cs

@ -92,7 +92,7 @@ public class OpenIddictDataSeedContributor : IDataSeedContributor, ITransientDep
private async Task CreateApplicationsAsync() private async Task CreateApplicationsAsync()
{ {
await _applicationManager.CreateAsync(await GetOpenIddictApplicationModelAsync(_testData.App1Id, new OpenIddictApplicationDescriptor await _applicationManager.CreateAsync(await GetOpenIddictApplicationModelAsync(_testData.App1Id, new AbpApplicationDescriptor
{ {
ClientId = _testData.App1ClientId, ClientId = _testData.App1ClientId,
ConsentType = OpenIddictConstants.ConsentTypes.Explicit, ConsentType = OpenIddictConstants.ConsentTypes.Explicit,
@ -137,10 +137,12 @@ public class OpenIddictDataSeedContributor : IDataSeedContributor, ITransientDep
OpenIddictConstants.Permissions.Scopes.Phone, OpenIddictConstants.Permissions.Scopes.Phone,
OpenIddictConstants.Permissions.Prefixes.Scope + _testData.Scope1Name OpenIddictConstants.Permissions.Prefixes.Scope + _testData.Scope1Name
} },
ClientUri = "https://abp.io/TestApplication",
LogoUri = "https://abp.io/TestApplication.png"
})); }));
await _applicationManager.CreateAsync(await GetOpenIddictApplicationModelAsync(_testData.App2Id, new OpenIddictApplicationDescriptor await _applicationManager.CreateAsync(await GetOpenIddictApplicationModelAsync(_testData.App2Id, new AbpApplicationDescriptor
{ {
ClientId = _testData.App2ClientId, ClientId = _testData.App2ClientId,
ConsentType = OpenIddictConstants.ConsentTypes.Explicit, ConsentType = OpenIddictConstants.ConsentTypes.Explicit,
@ -186,7 +188,9 @@ public class OpenIddictDataSeedContributor : IDataSeedContributor, ITransientDep
OpenIddictConstants.Permissions.Prefixes.Scope + _testData.Scope1Name, OpenIddictConstants.Permissions.Prefixes.Scope + _testData.Scope1Name,
OpenIddictConstants.Permissions.Prefixes.Scope + _testData.Scope2Name, OpenIddictConstants.Permissions.Prefixes.Scope + _testData.Scope2Name,
} },
ClientUri = "https://abp.io/TestApplication2",
LogoUri = "https://abp.io/TestApplication2.png"
})); }));
} }
@ -240,7 +244,6 @@ public class OpenIddictDataSeedContributor : IDataSeedContributor, ITransientDep
Subject = "TestSubject1", Subject = "TestSubject1",
Type = OpenIddictConstants.AuthorizationTypes.Permanent, Type = OpenIddictConstants.AuthorizationTypes.Permanent,
CreationDate = _clock.Now CreationDate = _clock.Now
})); }));
await _authorizationManager.CreateAsync(await GetOpenIddictAuthorizationModelAsync(_testData.Authorization2Id, new OpenIddictAuthorizationDescriptor await _authorizationManager.CreateAsync(await GetOpenIddictAuthorizationModelAsync(_testData.Authorization2Id, new OpenIddictAuthorizationDescriptor

2
templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Data/MyProjectNameEFCoreDbSchemaMigrator.cs

@ -15,7 +15,7 @@ public class MyProjectNameEFCoreDbSchemaMigrator : ITransientDependency
public async Task MigrateAsync() public async Task MigrateAsync()
{ {
/* We intentionally resolving the MyProjectNameDbContext /* We intentionally resolve the MyProjectNameDbContext
* from IServiceProvider (instead of directly injecting it) * from IServiceProvider (instead of directly injecting it)
* to properly get the connection string of the current tenant in the * to properly get the connection string of the current tenant in the
* current scope. * current scope.

2
templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Data/MyProjectNameEFCoreDbSchemaMigrator.cs

@ -15,7 +15,7 @@ public class MyProjectNameEFCoreDbSchemaMigrator : ITransientDependency
public async Task MigrateAsync() public async Task MigrateAsync()
{ {
/* We intentionally resolving the MyProjectNameDbContext /* We intentionally resolve the MyProjectNameDbContext
* from IServiceProvider (instead of directly injecting it) * from IServiceProvider (instead of directly injecting it)
* to properly get the connection string of the current tenant in the * to properly get the connection string of the current tenant in the
* current scope. * current scope.

2
templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Data/MyProjectNameEFCoreDbSchemaMigrator.cs

@ -15,7 +15,7 @@ public class MyProjectNameEFCoreDbSchemaMigrator : ITransientDependency
public async Task MigrateAsync() public async Task MigrateAsync()
{ {
/* We intentionally resolving the MyProjectNameDbContext /* We intentionally resolve the MyProjectNameDbContext
* from IServiceProvider (instead of directly injecting it) * from IServiceProvider (instead of directly injecting it)
* to properly get the connection string of the current tenant in the * to properly get the connection string of the current tenant in the
* current scope. * current scope.

2
templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Data/MyProjectNameEFCoreDbSchemaMigrator.cs

@ -15,7 +15,7 @@ public class MyProjectNameEFCoreDbSchemaMigrator : ITransientDependency
public async Task MigrateAsync() public async Task MigrateAsync()
{ {
/* We intentionally resolving the MyProjectNameDbContext /* We intentionally resolve the MyProjectNameDbContext
* from IServiceProvider (instead of directly injecting it) * from IServiceProvider (instead of directly injecting it)
* to properly get the connection string of the current tenant in the * to properly get the connection string of the current tenant in the
* current scope. * current scope.

2
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/EntityFrameworkCore/EntityFrameworkCoreMyProjectNameDbSchemaMigrator.cs

@ -20,7 +20,7 @@ public class EntityFrameworkCoreMyProjectNameDbSchemaMigrator
public async Task MigrateAsync() public async Task MigrateAsync()
{ {
/* We intentionally resolving the MyProjectNameDbContext /* We intentionally resolve the MyProjectNameDbContext
* from IServiceProvider (instead of directly injecting it) * from IServiceProvider (instead of directly injecting it)
* to properly get the connection string of the current tenant in the * to properly get the connection string of the current tenant in the
* current scope. * current scope.

Loading…
Cancel
Save