mirror of https://github.com/abpframework/abp.git
20 changed files with 350 additions and 11 deletions
@ -0,0 +1,12 @@ |
|||
namespace Volo.Abp.Emailing.Templates |
|||
{ |
|||
public class EmailTemplate |
|||
{ |
|||
public string Content { get; } |
|||
|
|||
public EmailTemplate(string content) |
|||
{ |
|||
Content = content; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,32 @@ |
|||
using System.Collections.Generic; |
|||
using JetBrains.Annotations; |
|||
|
|||
namespace Volo.Abp.Emailing.Templates |
|||
{ |
|||
public class EmailTemplateDefinition |
|||
{ |
|||
public string Name { get; } |
|||
|
|||
public Dictionary<string, object> Properties { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets/sets a key-value on the <see cref="Properties"/>.
|
|||
/// </summary>
|
|||
/// <param name="name">Name of the property</param>
|
|||
/// <returns>
|
|||
/// Returns the value in the <see cref="Properties"/> dictionary by given <see cref="name"/>.
|
|||
/// Returns null if given <see cref="name"/> is not present in the <see cref="Properties"/> dictionary.
|
|||
/// </returns>
|
|||
public object this[string name] |
|||
{ |
|||
get => Properties.GetOrDefault(name); |
|||
set => Properties[name] = value; |
|||
} |
|||
|
|||
public EmailTemplateDefinition([NotNull]string name) |
|||
{ |
|||
Name = Check.NotNullOrWhiteSpace(name, nameof(name)); |
|||
Properties = new Dictionary<string, object>(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using System.Collections.Generic; |
|||
|
|||
namespace Volo.Abp.Emailing.Templates |
|||
{ |
|||
public class EmailTemplateDefinitionDictionary : Dictionary<string, EmailTemplateDefinition> |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
using System.Collections.Generic; |
|||
using Volo.Abp.Emailing.Templates.Virtual; |
|||
|
|||
namespace Volo.Abp.Emailing.Templates |
|||
{ |
|||
public class EmailTemplateOptions |
|||
{ |
|||
public List<IEmailTemplateProvider> Providers { get; } |
|||
|
|||
public EmailTemplateDefinitionDictionary Templates { get; } |
|||
|
|||
public EmailTemplateOptions() |
|||
{ |
|||
Providers = new List<IEmailTemplateProvider> |
|||
{ |
|||
new VirtualFileEmailTemplateProvider() |
|||
}; |
|||
|
|||
Templates = new EmailTemplateDefinitionDictionary(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
using System; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Volo.Abp.Emailing.Templates |
|||
{ |
|||
public class EmailTemplateProviderContext : IServiceProviderAccessor |
|||
{ |
|||
public string Name { get; } |
|||
|
|||
public IServiceProvider ServiceProvider { get; } |
|||
|
|||
public EmailTemplate Template { get; set; } |
|||
|
|||
public EmailTemplateProviderContext(string name, IServiceProvider serviceProvider) |
|||
{ |
|||
Name = name; |
|||
ServiceProvider = serviceProvider; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,40 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Options; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Volo.Abp.Emailing.Templates |
|||
{ |
|||
public class EmailTemplateStore : IEmailTemplateStore, ITransientDependency |
|||
{ |
|||
protected IServiceProvider ServiceProvider { get; } |
|||
protected EmailTemplateOptions Options { get; } |
|||
|
|||
public EmailTemplateStore(IOptions<EmailTemplateOptions> options, IServiceProvider serviceProvider) |
|||
{ |
|||
ServiceProvider = serviceProvider; |
|||
Options = options.Value; |
|||
} |
|||
|
|||
public async Task<EmailTemplate> GetAsync(string name) |
|||
{ |
|||
using (var scope = ServiceProvider.CreateScope()) |
|||
{ |
|||
var context = new EmailTemplateProviderContext(name, scope.ServiceProvider); |
|||
foreach (var provider in Options.Providers) |
|||
{ |
|||
await provider.ProvideAsync(context); |
|||
} |
|||
|
|||
if (context.Template == null) |
|||
{ |
|||
//TODO: Return a default email template!
|
|||
throw new NotImplementedException(); |
|||
} |
|||
|
|||
return context.Template; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Volo.Abp.Emailing.Templates |
|||
{ |
|||
public interface IEmailTemplateProvider |
|||
{ |
|||
Task ProvideAsync(EmailTemplateProviderContext context); |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Volo.Abp.Emailing.Templates |
|||
{ |
|||
public interface IEmailTemplateStore |
|||
{ |
|||
Task<EmailTemplate> GetAsync(string name); |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
namespace Volo.Abp.Emailing.Templates.Virtual |
|||
{ |
|||
public static class EmailTemplateDefinitionExtensions |
|||
{ |
|||
public static EmailTemplateDefinition SetVirtualFilePath(this EmailTemplateDefinition emailTemplateDefinition, string path) |
|||
{ |
|||
emailTemplateDefinition[VirtualFileEmailTemplateProvider.VirtualFilePathKey] = path; |
|||
return emailTemplateDefinition; |
|||
} |
|||
|
|||
public static string GetVirtualFilePathOrNull(this EmailTemplateDefinition emailTemplateDefinition) |
|||
{ |
|||
return emailTemplateDefinition[VirtualFileEmailTemplateProvider.VirtualFilePathKey] as string; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
using System.Collections.Generic; |
|||
|
|||
namespace Volo.Abp.Emailing.Templates.Virtual |
|||
{ |
|||
public class VirtualFileEmailTemplateOptions |
|||
{ |
|||
public IDictionary<string, string> Templates { get; } |
|||
|
|||
public VirtualFileEmailTemplateOptions() |
|||
{ |
|||
Templates = new Dictionary<string, string>(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,61 @@ |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.FileProviders; |
|||
using Microsoft.Extensions.Options; |
|||
using Volo.Abp.VirtualFileSystem; |
|||
|
|||
namespace Volo.Abp.Emailing.Templates.Virtual |
|||
{ |
|||
public class VirtualFileEmailTemplateProvider : IEmailTemplateProvider |
|||
{ |
|||
public const string VirtualFilePathKey = "VirtualFilePath"; |
|||
|
|||
public Task ProvideAsync(EmailTemplateProviderContext context) |
|||
{ |
|||
var templateDefinition = FindTemplateDefinition(context); |
|||
if (templateDefinition == null) |
|||
{ |
|||
return Task.CompletedTask; |
|||
} |
|||
|
|||
var fileInfo = FindVirtualFileInfo(context, templateDefinition); |
|||
if (fileInfo == null) |
|||
{ |
|||
return Task.CompletedTask; |
|||
} |
|||
|
|||
context.Template = new EmailTemplate(fileInfo.ReadAsString()); |
|||
return Task.CompletedTask; |
|||
} |
|||
|
|||
protected virtual EmailTemplateDefinition FindTemplateDefinition(EmailTemplateProviderContext context) |
|||
{ |
|||
return context |
|||
.ServiceProvider |
|||
.GetRequiredService<IOptions<EmailTemplateOptions>>() |
|||
.Value |
|||
.Templates |
|||
.GetOrDefault(context.Name); |
|||
} |
|||
|
|||
protected virtual IFileInfo FindVirtualFileInfo(EmailTemplateProviderContext context, EmailTemplateDefinition templateDefinition) |
|||
{ |
|||
var virtualFilePath = templateDefinition?.GetVirtualFilePathOrNull(); |
|||
if (virtualFilePath == null) |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
var virtualFileProvider = context.ServiceProvider.GetRequiredService<IVirtualFileProvider>(); |
|||
|
|||
var fileInfo = virtualFileProvider.GetFileInfo(virtualFilePath); |
|||
if (fileInfo?.Exists != true) |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
return fileInfo; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netcoreapp2.1</TargetFramework> |
|||
<LangVersion>latest</LangVersion> |
|||
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<EmbeddedResource Include="Volo\Abp\Emailing\TestTemplates\*.*" /> |
|||
<None Remove="Volo\Abp\Emailing\TestTemplates\*.*" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\src\Volo.Abp.Emailing\Volo.Abp.Emailing.csproj" /> |
|||
<ProjectReference Include="..\AbpTestBase\AbpTestBase.csproj" /> |
|||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.2" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,29 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.Emailing.Templates; |
|||
using Volo.Abp.Emailing.Templates.Virtual; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.VirtualFileSystem; |
|||
|
|||
namespace Volo.Abp.Emailing |
|||
{ |
|||
[DependsOn( |
|||
typeof(AbpEmailingModule), |
|||
typeof(AbpTestBaseModule))] |
|||
public class AbpEmailingTestModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
context.Services.Configure<VirtualFileSystemOptions>(options => |
|||
{ |
|||
options.FileSets.AddEmbedded<AbpEmailingTestModule>(); |
|||
}); |
|||
|
|||
context.Services.Configure<EmailTemplateOptions>(options => |
|||
{ |
|||
options.Templates["template1"] = |
|||
new EmailTemplateDefinition("template1") |
|||
.SetVirtualFilePath("/Volo/Abp/Emailing/TestTemplates/template1.html"); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
using System.Threading.Tasks; |
|||
using Shouldly; |
|||
using Volo.Abp.Emailing.Templates; |
|||
using Xunit; |
|||
|
|||
namespace Volo.Abp.Emailing |
|||
{ |
|||
public class EmailTemplateStore_Tests : AbpIntegratedTest<AbpEmailingTestModule> |
|||
{ |
|||
private readonly IEmailTemplateStore _emailTemplateStore; |
|||
|
|||
public EmailTemplateStore_Tests() |
|||
{ |
|||
_emailTemplateStore = GetRequiredService<IEmailTemplateStore>(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_Get_Registered_Template() |
|||
{ |
|||
var template = await _emailTemplateStore.GetAsync("template1"); |
|||
template.Content.ShouldContain("This is a test template!"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
<!DOCTYPE html> |
|||
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"> |
|||
<head> |
|||
<meta charset="utf-8" /> |
|||
</head> |
|||
<body> |
|||
This is a test template! |
|||
</body> |
|||
</html> |
|||
Loading…
Reference in new issue