diff --git a/framework/Volo.Abp.sln b/framework/Volo.Abp.sln
index 3c3336de1f..13ef057f97 100644
--- a/framework/Volo.Abp.sln
+++ b/framework/Volo.Abp.sln
@@ -242,9 +242,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Ldap", "src\Volo.A
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Ldap.Tests", "test\Volo.Abp.Ldap.Tests\Volo.Abp.Ldap.Tests.csproj", "{38FB8F75-426E-4265-8D0E-E121837B6FCC}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Dapper", "src\Volo.Abp.Dapper\Volo.Abp.Dapper.csproj", "{D863A3C3-CC1D-426F-BDD4-02E7AE2A3170}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Dapper", "src\Volo.Abp.Dapper\Volo.Abp.Dapper.csproj", "{D863A3C3-CC1D-426F-BDD4-02E7AE2A3170}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Dapper.Tests", "test\Volo.Abp.Dapper.Tests\Volo.Abp.Dapper.Tests.csproj", "{E026A085-D881-4AE0-9F08-422AC3903BD7}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Dapper.Tests", "test\Volo.Abp.Dapper.Tests\Volo.Abp.Dapper.Tests.csproj", "{E026A085-D881-4AE0-9F08-422AC3903BD7}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.MailKit", "src\Volo.Abp.MailKit\Volo.Abp.MailKit.csproj", "{0CAED4CC-1CFD-4092-A326-AFE4DB3A9AB4}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.MailKit.Tests", "test\Volo.Abp.MailKit.Tests\Volo.Abp.MailKit.Tests.csproj", "{70DD6E17-B98B-4B00-8F38-C489E291BB53}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -732,6 +736,14 @@ Global
{E026A085-D881-4AE0-9F08-422AC3903BD7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E026A085-D881-4AE0-9F08-422AC3903BD7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E026A085-D881-4AE0-9F08-422AC3903BD7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0CAED4CC-1CFD-4092-A326-AFE4DB3A9AB4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0CAED4CC-1CFD-4092-A326-AFE4DB3A9AB4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0CAED4CC-1CFD-4092-A326-AFE4DB3A9AB4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0CAED4CC-1CFD-4092-A326-AFE4DB3A9AB4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {70DD6E17-B98B-4B00-8F38-C489E291BB53}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {70DD6E17-B98B-4B00-8F38-C489E291BB53}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {70DD6E17-B98B-4B00-8F38-C489E291BB53}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {70DD6E17-B98B-4B00-8F38-C489E291BB53}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -857,6 +869,8 @@ Global
{38FB8F75-426E-4265-8D0E-E121837B6FCC} = {447C8A77-E5F0-4538-8687-7383196D04EA}
{D863A3C3-CC1D-426F-BDD4-02E7AE2A3170} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{E026A085-D881-4AE0-9F08-422AC3903BD7} = {447C8A77-E5F0-4538-8687-7383196D04EA}
+ {0CAED4CC-1CFD-4092-A326-AFE4DB3A9AB4} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
+ {70DD6E17-B98B-4B00-8F38-C489E291BB53} = {447C8A77-E5F0-4538-8687-7383196D04EA}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5}
diff --git a/framework/src/Volo.Abp.MailKit/Volo.Abp.MailKit.csproj b/framework/src/Volo.Abp.MailKit/Volo.Abp.MailKit.csproj
new file mode 100644
index 0000000000..8af1220e76
--- /dev/null
+++ b/framework/src/Volo.Abp.MailKit/Volo.Abp.MailKit.csproj
@@ -0,0 +1,24 @@
+
+
+
+
+
+ netstandard2.0
+ Volo.Abp.MailKit
+ Volo.Abp.MailKit
+ $(AssetTargetFallback);portable-net45+win8+wp8+wpa81;
+ false
+ false
+ false
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.MailKit/Volo/Abp/MailKit/AbpMailKitModule.cs b/framework/src/Volo.Abp.MailKit/Volo/Abp/MailKit/AbpMailKitModule.cs
new file mode 100644
index 0000000000..9027172cf4
--- /dev/null
+++ b/framework/src/Volo.Abp.MailKit/Volo/Abp/MailKit/AbpMailKitModule.cs
@@ -0,0 +1,11 @@
+using Volo.Abp.Emailing;
+using Volo.Abp.Modularity;
+
+namespace Volo.Abp.MailKit
+{
+ [DependsOn(typeof(AbpEmailingModule))]
+ public class AbpMailKitModule : AbpModule
+ {
+
+ }
+}
diff --git a/framework/src/Volo.Abp.MailKit/Volo/Abp/MailKit/AbpMailKitOptions.cs b/framework/src/Volo.Abp.MailKit/Volo/Abp/MailKit/AbpMailKitOptions.cs
new file mode 100644
index 0000000000..fd25f0f7f7
--- /dev/null
+++ b/framework/src/Volo.Abp.MailKit/Volo/Abp/MailKit/AbpMailKitOptions.cs
@@ -0,0 +1,9 @@
+using MailKit.Security;
+
+namespace Volo.Abp.MailKit
+{
+ public class AbpMailKitOptions
+ {
+ public SecureSocketOptions? SecureSocketOption { get; set; }
+ }
+}
diff --git a/framework/src/Volo.Abp.MailKit/Volo/Abp/MailKit/IMailKitSmtpEmailSender.cs b/framework/src/Volo.Abp.MailKit/Volo/Abp/MailKit/IMailKitSmtpEmailSender.cs
new file mode 100644
index 0000000000..54514814fc
--- /dev/null
+++ b/framework/src/Volo.Abp.MailKit/Volo/Abp/MailKit/IMailKitSmtpEmailSender.cs
@@ -0,0 +1,11 @@
+using System.Threading.Tasks;
+using MailKit.Net.Smtp;
+using Volo.Abp.Emailing;
+
+namespace Volo.Abp.MailKit
+{
+ public interface IMailKitSmtpEmailSender: IEmailSender
+ {
+ Task BuildClientAsync();
+ }
+}
diff --git a/framework/src/Volo.Abp.MailKit/Volo/Abp/MailKit/MailKitSmtpEmailSender.cs b/framework/src/Volo.Abp.MailKit/Volo/Abp/MailKit/MailKitSmtpEmailSender.cs
new file mode 100644
index 0000000000..426be33c80
--- /dev/null
+++ b/framework/src/Volo.Abp.MailKit/Volo/Abp/MailKit/MailKitSmtpEmailSender.cs
@@ -0,0 +1,99 @@
+using System.Net.Mail;
+using System.Threading.Tasks;
+using Volo.Abp.BackgroundJobs;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.Emailing;
+using Volo.Abp.Emailing.Smtp;
+using MailKit.Security;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Options;
+using MimeKit;
+using Volo.Abp.Threading;
+using SmtpClient = MailKit.Net.Smtp.SmtpClient;
+
+namespace Volo.Abp.MailKit
+{
+ [Dependency(ServiceLifetime.Transient, ReplaceServices = true)]
+ public class MailKitSmtpEmailSender : EmailSenderBase, IMailKitSmtpEmailSender
+ {
+ protected AbpMailKitOptions AbpMailKitOptions { get; }
+
+ protected ISmtpEmailSenderConfiguration SmtpConfiguration { get; }
+
+ public MailKitSmtpEmailSender(ISmtpEmailSenderConfiguration smtpConfiguration,
+ IBackgroundJobManager backgroundJobManager,
+ IOptions abpMailKitConfiguration)
+ : base(smtpConfiguration, backgroundJobManager)
+ {
+ AbpMailKitOptions = abpMailKitConfiguration.Value;
+ SmtpConfiguration = smtpConfiguration;
+ }
+
+ protected override async Task SendEmailAsync(MailMessage mail)
+ {
+ using (var client = await BuildClientAsync())
+ {
+ var message = MimeMessage.CreateFromMailMessage(mail);
+ await client.SendAsync(message);
+ await client.DisconnectAsync(true);
+ }
+ }
+
+ protected override void SendEmail(MailMessage mail)
+ {
+ using (var client = AsyncHelper.RunSync(BuildClientAsync))
+ {
+ var message = MimeMessage.CreateFromMailMessage(mail);
+ client.Send(message);
+ client.Disconnect(true);
+ }
+ }
+
+ public async Task BuildClientAsync()
+ {
+ var client = new SmtpClient();
+
+ try
+ {
+ await ConfigureClient(client);
+ return client;
+ }
+ catch
+ {
+ client.Dispose();
+ throw;
+ }
+ }
+
+ protected virtual async Task ConfigureClient(SmtpClient client)
+ {
+ client.Connect(
+ await SmtpConfiguration.GetHostAsync(),
+ await SmtpConfiguration.GetPortAsync(),
+ await GetSecureSocketOption()
+ );
+
+ if (await SmtpConfiguration.GetUseDefaultCredentialsAsync())
+ {
+ return;
+ }
+
+ client.Authenticate(
+ await SmtpConfiguration.GetUserNameAsync(),
+ await SmtpConfiguration.GetPasswordAsync()
+ );
+ }
+
+ protected virtual async Task GetSecureSocketOption()
+ {
+ if (AbpMailKitOptions.SecureSocketOption.HasValue)
+ {
+ return AbpMailKitOptions.SecureSocketOption.Value;
+ }
+
+ return await SmtpConfiguration.GetEnableSslAsync()
+ ? SecureSocketOptions.SslOnConnect
+ : SecureSocketOptions.StartTlsWhenAvailable;
+ }
+ }
+}
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 831258c5d5..2746da3847 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,4 +1,5 @@
-using Volo.Abp.Emailing.Localization;
+using Volo.Abp.Autofac;
+using Volo.Abp.Emailing.Localization;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
@@ -7,6 +8,7 @@ namespace Volo.Abp.Emailing
{
[DependsOn(
typeof(AbpEmailingModule),
+ typeof(AbpAutofacModule),
typeof(AbpTestBaseModule))]
public class AbpEmailingTestModule : AbpModule
{
diff --git a/framework/test/Volo.Abp.MailKit.Tests/Volo.Abp.MailKit.Tests.csproj b/framework/test/Volo.Abp.MailKit.Tests/Volo.Abp.MailKit.Tests.csproj
new file mode 100644
index 0000000000..17097b1bf0
--- /dev/null
+++ b/framework/test/Volo.Abp.MailKit.Tests/Volo.Abp.MailKit.Tests.csproj
@@ -0,0 +1,20 @@
+
+
+
+ netcoreapp2.2
+ latest
+ true
+ false
+ false
+ false
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/framework/test/Volo.Abp.MailKit.Tests/Volo/Abp/MailKit/AbpMailKitTestModule.cs b/framework/test/Volo.Abp.MailKit.Tests/Volo/Abp/MailKit/AbpMailKitTestModule.cs
new file mode 100644
index 0000000000..b0d6e9f7da
--- /dev/null
+++ b/framework/test/Volo.Abp.MailKit.Tests/Volo/Abp/MailKit/AbpMailKitTestModule.cs
@@ -0,0 +1,13 @@
+using Volo.Abp.Autofac;
+using Volo.Abp.Modularity;
+
+namespace Volo.Abp.MailKit
+{
+ [DependsOn(
+ typeof(AbpMailKitModule),
+ typeof(AbpAutofacModule),
+ typeof(AbpTestBaseModule))]
+ public class AbpMailKitTestModule :AbpModule
+ {
+ }
+}
diff --git a/framework/test/Volo.Abp.MailKit.Tests/Volo/Abp/MailKit/MailKitSmtpEmailSender_Tests.cs b/framework/test/Volo.Abp.MailKit.Tests/Volo/Abp/MailKit/MailKitSmtpEmailSender_Tests.cs
new file mode 100644
index 0000000000..8404b8df4e
--- /dev/null
+++ b/framework/test/Volo.Abp.MailKit.Tests/Volo/Abp/MailKit/MailKitSmtpEmailSender_Tests.cs
@@ -0,0 +1,48 @@
+using System.Net.Mail;
+using System.Threading.Tasks;
+using NSubstitute;
+using Volo.Abp.BackgroundJobs;
+using Volo.Abp.Emailing.Smtp;
+using Xunit;
+
+namespace Volo.Abp.MailKit
+{
+ //Tests are commented because those tests can pass only when a true email configuration is set.
+ public class MailKitSmtpEmailSender_Tests : AbpIntegratedTest
+ {
+ //[Fact]
+ public async Task ShouldSendMailMessageAsync()
+ {
+ var mailSender = CreateMailKitEmailSender();
+ var mailMessage = new MailMessage("from_mail_address@asd.com", "to_mail_address@asd.com", "subject", "body")
+ { IsBodyHtml = true };
+
+ await mailSender.SendAsync(mailMessage);
+ }
+
+ //[Fact]
+ public void ShouldSendMailMessage()
+ {
+ var mailSender = CreateMailKitEmailSender();
+ var mailMessage = new MailMessage("from_mail_address@asd.com", "to_mail_address@asd.com", "subject", "body")
+ { IsBodyHtml = true };
+
+ mailSender.Send(mailMessage);
+ }
+
+ private static MailKitSmtpEmailSender CreateMailKitEmailSender()
+ {
+ var mailConfig = Substitute.For();
+ var bgJob = Substitute.For();
+
+ mailConfig.GetHostAsync().Returns(Task.FromResult("stmp_server_name"));
+ mailConfig.GetUserNameAsync().Returns(Task.FromResult("mail_server_user_name"));
+ mailConfig.GetPasswordAsync().Returns(Task.FromResult("mail_server_password"));
+ mailConfig.GetPortAsync().Returns(Task.FromResult(587));
+ mailConfig.GetEnableSslAsync().Returns(Task.FromResult(false));
+
+ var mailSender = new MailKitSmtpEmailSender(mailConfig, bgJob, null);
+ return mailSender;
+ }
+ }
+}
diff --git a/modules/account/src/Volo.Abp.Account.Application/Volo.Abp.Account.Application.csproj b/modules/account/src/Volo.Abp.Account.Application/Volo.Abp.Account.Application.csproj
index 097e1f6c55..14f9c8f991 100644
--- a/modules/account/src/Volo.Abp.Account.Application/Volo.Abp.Account.Application.csproj
+++ b/modules/account/src/Volo.Abp.Account.Application/Volo.Abp.Account.Application.csproj
@@ -13,7 +13,6 @@
-
diff --git a/modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/AbpAccountApplicationModule.cs b/modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/AbpAccountApplicationModule.cs
index 8fecc2d4e0..601ce9a3d3 100644
--- a/modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/AbpAccountApplicationModule.cs
+++ b/modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/AbpAccountApplicationModule.cs
@@ -1,5 +1,4 @@
-using Volo.Abp.Emailing;
-using Volo.Abp.Identity;
+using Volo.Abp.Identity;
using Volo.Abp.Modularity;
using Volo.Abp.UI.Navigation.Urls;
using Volo.Abp.UI.Navigation;
@@ -9,7 +8,6 @@ namespace Volo.Abp.Account
{
[DependsOn(
typeof(AbpAccountApplicationContractsModule),
- typeof(AbpEmailingModule),
typeof(AbpIdentityApplicationModule),
typeof(AbpUiNavigationModule)
)]
diff --git a/nupkg/common.ps1 b/nupkg/common.ps1
index eaea068daa..24a73876a7 100644
--- a/nupkg/common.ps1
+++ b/nupkg/common.ps1
@@ -81,6 +81,7 @@ $projects = (
"framework/src/Volo.Abp.Json",
"framework/src/Volo.Abp.Ldap",
"framework/src/Volo.Abp.Localization.Abstractions",
+ "framework/src/Volo.Abp.MailKit",
"framework/src/Volo.Abp.Localization",
"framework/src/Volo.Abp.MemoryDb",
"framework/src/Volo.Abp.MongoDB",