diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/AbpEmailingModule.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/AbpEmailingModule.cs index b861a3898c..035d6de30a 100644 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/AbpEmailingModule.cs +++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/AbpEmailingModule.cs @@ -1,6 +1,8 @@ -using Volo.Abp.BackgroundJobs; +using System; +using System.Collections.Generic; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.BackgroundJobs; using Volo.Abp.Emailing.Templates; -using Volo.Abp.Emailing.Templates.Virtual; using Volo.Abp.Localization; using Volo.Abp.Modularity; using Volo.Abp.Settings; @@ -16,6 +18,11 @@ namespace Volo.Abp.Emailing )] public class AbpEmailingModule : AbpModule { + public override void PreConfigureServices(ServiceConfigurationContext context) + { + AutoAddDefinitionProviders(context.Services); + } + public override void ConfigureServices(ServiceConfigurationContext context) { Configure(options => @@ -27,18 +34,26 @@ namespace Volo.Abp.Emailing { options.AddJob(); }); + } + + private static void AutoAddDefinitionProviders(IServiceCollection services) + { + var definitionProviders = new List(); - Configure(options => + services.OnRegistred(context => { - options.Templates - .Add( - new EmailTemplateDefinition(StandardEmailTemplates.DefaultLayout, isLayout: true, layout: null) - .SetVirtualFilePath("/Volo/Abp/Emailing/Templates/DefaultLayout.html") - ).Add( - new EmailTemplateDefinition(StandardEmailTemplates.SimpleMessage) - .SetVirtualFilePath("/Volo/Abp/Emailing/Templates/SimpleMessageTemplate.html") - ); + + if (typeof(IEmailTemplateDefinitionProvider).IsAssignableFrom(context.ImplementationType)) + { + definitionProviders.Add(context.ImplementationType); + } + }); + + services.Configure(options => + { + options.DefinitionProviders.AddIfNotContains(definitionProviders); }); } + } } diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/DefaultEmailTemplateProvider.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/DefaultEmailTemplateProvider.cs new file mode 100644 index 0000000000..cc7f1ff4ed --- /dev/null +++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/DefaultEmailTemplateProvider.cs @@ -0,0 +1,16 @@ +using Volo.Abp.Emailing.Templates.Virtual; + +namespace Volo.Abp.Emailing.Templates +{ + public class DefaultEmailTemplateProvider : EmailTemplateDefinitionProvider + { + public override void Define(IEmailTemplateDefinitionContext context) + { + context.Add(new EmailTemplateDefinition(StandardEmailTemplates.DefaultLayout, isLayout: true, layout: null) + .SetVirtualFilePath("/Volo/Abp/Emailing/Templates/DefaultLayout.html")); + + context.Add(new EmailTemplateDefinition(StandardEmailTemplates.SimpleMessage) + .SetVirtualFilePath("/Volo/Abp/Emailing/Templates/SimpleMessageTemplate.html")); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateDefinitionContext.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateDefinitionContext.cs new file mode 100644 index 0000000000..03a6c95d8b --- /dev/null +++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateDefinitionContext.cs @@ -0,0 +1,38 @@ +using System.Collections.Generic; +using System.Collections.Immutable; + +namespace Volo.Abp.Emailing.Templates +{ + public class EmailTemplateDefinitionContext : IEmailTemplateDefinitionContext + { + protected Dictionary EmailTemplates { get; } + + public EmailTemplateDefinitionContext(Dictionary emailTemplates) + { + EmailTemplates = emailTemplates; + } + + public virtual EmailTemplateDefinition GetOrNull(string name) + { + return EmailTemplates.GetOrDefault(name); + } + + public virtual IReadOnlyList GetAll() + { + return EmailTemplates.Values.ToImmutableList(); + } + + public virtual void Add(params EmailTemplateDefinition[] definitions) + { + if (definitions.IsNullOrEmpty()) + { + return; + } + + foreach (var definition in definitions) + { + EmailTemplates[definition.Name] = definition; + } + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateDefinitionManager.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateDefinitionManager.cs new file mode 100644 index 0000000000..a6a58aef27 --- /dev/null +++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateDefinitionManager.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Emailing.Templates +{ + public class EmailTemplateDefinitionManager : IEmailTemplateDefinitionManager, ISingletonDependency + { + protected Lazy> EmailTemplateDefinitions { get; } + + protected EmailTemplateOptions Options { get; } + + protected IServiceProvider ServiceProvider { get; } + + public EmailTemplateDefinitionManager( + IOptions options, + IServiceProvider serviceProvider) + { + ServiceProvider = serviceProvider; + Options = options.Value; + + EmailTemplateDefinitions = + new Lazy>(CreateEmailTemplateDefinitions, true); + } + + public virtual EmailTemplateDefinition Get(string name) + { + Check.NotNull(name, nameof(name)); + + var template = GetOrNull(name); + + if (template == null) + { + throw new AbpException("Undefined template: " + name); + } + + return template; + } + + public virtual IReadOnlyList GetAll() + { + return EmailTemplateDefinitions.Value.Values.ToImmutableList(); + } + + public virtual EmailTemplateDefinition GetOrNull(string name) + { + return EmailTemplateDefinitions.Value.GetOrDefault(name); + } + + protected virtual IDictionary CreateEmailTemplateDefinitions() + { + var templates = new Dictionary(); + + using (var scope = ServiceProvider.CreateScope()) + { + var providers = Options + .DefinitionProviders + .Select(p => scope.ServiceProvider.GetRequiredService(p) as IEmailTemplateDefinitionProvider) + .ToList(); + + foreach (var provider in providers) + { + provider.Define(new EmailTemplateDefinitionContext(templates)); + } + } + + return templates; + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateDefinitionProvider.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateDefinitionProvider.cs new file mode 100644 index 0000000000..e53505fafc --- /dev/null +++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateDefinitionProvider.cs @@ -0,0 +1,9 @@ +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Emailing.Templates +{ + public abstract class EmailTemplateDefinitionProvider : IEmailTemplateDefinitionProvider, ITransientDependency + { + public abstract void Define(IEmailTemplateDefinitionContext context); + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateOptions.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateOptions.cs index 6d10bd562e..06ab12e8a2 100644 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateOptions.cs +++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateOptions.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using Volo.Abp.Collections; using Volo.Abp.Emailing.Templates.Virtual; namespace Volo.Abp.Emailing.Templates @@ -7,10 +8,10 @@ namespace Volo.Abp.Emailing.Templates { public List Providers { get; } - public EmailTemplateDefinitionDictionary Templates { get; } - public string DefaultLayout { get; set; } + public ITypeList DefinitionProviders { get; } + public EmailTemplateOptions() { Providers = new List @@ -18,9 +19,9 @@ namespace Volo.Abp.Emailing.Templates new VirtualFileEmailTemplateProviderContributor() }; - Templates = new EmailTemplateDefinitionDictionary(); - DefaultLayout = StandardEmailTemplates.DefaultLayout; + + DefinitionProviders = new TypeList(); } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateDefinitionContext.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateDefinitionContext.cs new file mode 100644 index 0000000000..1641562ccf --- /dev/null +++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateDefinitionContext.cs @@ -0,0 +1,9 @@ +namespace Volo.Abp.Emailing.Templates +{ + public interface IEmailTemplateDefinitionContext + { + EmailTemplateDefinition GetOrNull(string name); + + void Add(params EmailTemplateDefinition[] definitions); + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateDefinitionManager.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateDefinitionManager.cs new file mode 100644 index 0000000000..0936a2fe93 --- /dev/null +++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateDefinitionManager.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using JetBrains.Annotations; + +namespace Volo.Abp.Emailing.Templates +{ + public interface IEmailTemplateDefinitionManager + { + [NotNull] + EmailTemplateDefinition Get([NotNull] string name); + + IReadOnlyList GetAll(); + + EmailTemplateDefinition GetOrNull(string name); + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateDefinitionProvider.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateDefinitionProvider.cs new file mode 100644 index 0000000000..691d3874d6 --- /dev/null +++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateDefinitionProvider.cs @@ -0,0 +1,7 @@ +namespace Volo.Abp.Emailing.Templates +{ + public interface IEmailTemplateDefinitionProvider + { + void Define(IEmailTemplateDefinitionContext context); + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/Virtual/VirtualFileEmailTemplateProviderContributor.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/Virtual/VirtualFileEmailTemplateProviderContributor.cs index d54f4c94cb..3fb7e8d952 100644 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/Virtual/VirtualFileEmailTemplateProviderContributor.cs +++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/Virtual/VirtualFileEmailTemplateProviderContributor.cs @@ -33,10 +33,8 @@ namespace Volo.Abp.Emailing.Templates.Virtual { return contributorContext .ServiceProvider - .GetRequiredService>() - .Value - .Templates - .GetOrDefault(contributorContext.Name); + .GetRequiredService() + .GetOrNull(contributorContext.Name); } protected virtual IFileInfo FindVirtualFileInfo(EmailTemplateProviderContributorContext contributorContext, EmailTemplateDefinition templateDefinition) diff --git a/framework/test/Volo.Abp.Emailing.Tests/Volo.Abp.Emailing.Tests.csproj b/framework/test/Volo.Abp.Emailing.Tests/Volo.Abp.Emailing.Tests.csproj index 32b4f25816..fc77dac001 100644 --- a/framework/test/Volo.Abp.Emailing.Tests/Volo.Abp.Emailing.Tests.csproj +++ b/framework/test/Volo.Abp.Emailing.Tests/Volo.Abp.Emailing.Tests.csproj @@ -1,4 +1,4 @@ - + netcoreapp2.2 @@ -17,6 +17,7 @@ + diff --git a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/AbpEmailingTestModule.cs b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/AbpEmailingTestModule.cs index a36c664e8a..9b290acd74 100644 --- a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/AbpEmailingTestModule.cs +++ b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/AbpEmailingTestModule.cs @@ -1,7 +1,4 @@ -using Microsoft.Extensions.DependencyInjection; -using Volo.Abp.Emailing.Templates; -using Volo.Abp.Emailing.Templates.Virtual; -using Volo.Abp.Modularity; +using Volo.Abp.Modularity; using Volo.Abp.VirtualFileSystem; namespace Volo.Abp.Emailing @@ -17,13 +14,6 @@ namespace Volo.Abp.Emailing { options.FileSets.AddEmbedded(); }); - - Configure(options => - { - options.Templates["template1"] = - new EmailTemplateDefinition("template1") - .SetVirtualFilePath("/Volo/Abp/Emailing/TestTemplates/template1.html"); - }); } } -} +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/EmailTemplateStore_Tests.cs b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/EmailTemplateStore_Tests.cs index a09fb48ed1..b2fec29371 100644 --- a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/EmailTemplateStore_Tests.cs +++ b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/EmailTemplateStore_Tests.cs @@ -1,4 +1,4 @@ -using System.Threading.Tasks; +using System.Threading.Tasks; using Shouldly; using Volo.Abp.Emailing.Templates; using Xunit; @@ -7,6 +7,11 @@ namespace Volo.Abp.Emailing { public class EmailTemplateStore_Tests : AbpIntegratedTest { + protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) + { + options.UseAutofac(); + } + private readonly IEmailTemplateProvider _emailTemplateProvider; public EmailTemplateStore_Tests() diff --git a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/TestEmailTemplateProvider.cs b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/TestEmailTemplateProvider.cs new file mode 100644 index 0000000000..379371c727 --- /dev/null +++ b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/TestEmailTemplateProvider.cs @@ -0,0 +1,14 @@ +using Volo.Abp.Emailing.Templates; +using Volo.Abp.Emailing.Templates.Virtual; + +namespace Volo.Abp.Emailing +{ + public class TestEmailTemplateProvider : EmailTemplateDefinitionProvider + { + public override void Define(IEmailTemplateDefinitionContext context) + { + context.Add(new EmailTemplateDefinition("template1") + .SetVirtualFilePath("/Volo/Abp/Emailing/TestTemplates/template1.html")); + } + } +} \ No newline at end of file