Skip to content

Commit

Permalink
Updated sample to use _mailFolderCache.GetMailFolderAsync
Browse files Browse the repository at this point in the history
  • Loading branch information
danzuep committed Jun 10, 2024
1 parent 2b3c3e1 commit 256569b
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 32 deletions.
4 changes: 2 additions & 2 deletions samples/WorkerServiceExample/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
{
services.AddHostedService<ExampleNamespace.Worker>();
//services.AddMailKitSimplifiedEmail(context.Configuration);
services.AddMailKitSimplifiedEmailSender(context.Configuration);
services.AddMailKitSimplifiedEmailReceiver(context.Configuration);
services.AddScopedMailKitSimplifiedEmailSender(context.Configuration);
services.AddScopedMailKitSimplifiedEmailReceiver(context.Configuration);
})
.Build();

Expand Down
27 changes: 19 additions & 8 deletions samples/WorkerServiceExample/Worker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,23 @@
using MailKitSimplified.Receiver.Extensions;
using MailKitSimplified.Receiver.Services;
using MailKitSimplified.Sender.Abstractions;
using System.Threading;

namespace ExampleNamespace;

public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
private readonly IServiceScopeFactory _serviceScopeFactory;
private readonly ISmtpSender _smtpSender;
private readonly IImapReceiver _imapReceiver;
private readonly IImapReceiverFactory _imapReceiverFactory;
private readonly IMailFolderMonitorFactory _mailFolderMonitorFactory;
private readonly ILoggerFactory _loggerFactory;

public Worker(ISmtpSender smtpSender, IImapReceiver imapReceiver, IImapReceiverFactory imapReceiverFactory, IMailFolderMonitorFactory mailFolderMonitorFactory, ILoggerFactory loggerFactory)
public Worker(IServiceScopeFactory serviceScopeFactory, ISmtpSender smtpSender, IImapReceiver imapReceiver, ILoggerFactory loggerFactory)
{
_logger = loggerFactory.CreateLogger<Worker>();
_serviceScopeFactory = serviceScopeFactory;
_smtpSender = smtpSender;
_imapReceiver = imapReceiver;
_imapReceiverFactory = imapReceiverFactory;
_mailFolderMonitorFactory = mailFolderMonitorFactory;
_loggerFactory = loggerFactory;
}

Expand Down Expand Up @@ -59,7 +56,9 @@ private static ImapReceiver CreateExchangeOAuth2ImapClientExample(SaslMechanismO

private async Task ImapReceiverFactoryAsync(CancellationToken cancellationToken = default)
{
var receivers = _imapReceiverFactory.GetAllImapReceivers();
using var scope = _serviceScopeFactory.CreateScope();
var imapReceiverFactory = scope.ServiceProvider.GetRequiredService<IImapReceiverFactory>();
var receivers = imapReceiverFactory.GetAllImapReceivers();
foreach (var receiver in receivers)
{
cancellationToken.ThrowIfCancellationRequested();
Expand All @@ -71,9 +70,21 @@ private async Task ImapReceiverFactoryAsync(CancellationToken cancellationToken

private async Task MailFolderMonitorFactoryAsync(CancellationToken cancellationToken = default)
{
using var scope = _serviceScopeFactory.CreateScope();
var mailFolderMonitorFactory = scope.ServiceProvider.GetRequiredService<IMailFolderMonitorFactory>();
void LogUniqueIdArrived(IMessageSummary messageSummary) =>
_logger.LogInformation($"Message #{messageSummary.UniqueId} arrived.");
await _mailFolderMonitorFactory.MonitorAllMailboxesAsync(LogUniqueIdArrived, cancellationToken);
await mailFolderMonitorFactory.MonitorAllMailboxesAsync(LogUniqueIdArrived, cancellationToken);
}

private async Task MailFolderMonitorMoveFolderAsync(string destinationFolderFullName, CancellationToken cancellationToken = default)
{
using var scope = _serviceScopeFactory.CreateScope();
var mailFolderClient = scope.ServiceProvider.GetRequiredService<IMailFolderClient>();
var mailFolderMonitorFactory = scope.ServiceProvider.GetRequiredService<IMailFolderMonitorFactory>();
async Task UniqueIdArrivedAsync(IMessageSummary messageSummary) =>
await mailFolderClient.MoveToAsync(messageSummary, destinationFolderFullName, cancellationToken);
await mailFolderMonitorFactory.MonitorAllMailboxesAsync(UniqueIdArrivedAsync, cancellationToken);
}

private async Task DownloadEmailAsync(string filePath = "download.eml", CancellationToken cancellationToken = default)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,6 @@ public interface IImapReceiver : IAsyncDisposable, IDisposable
/// <returns>Connected <see cref="IMailFolder"/>.</returns>
ValueTask<IMailFolder> ConnectMailFolderAsync(CancellationToken cancellationToken = default);

/// <summary>
/// Connect to the given mail folder.
/// </summary>
/// <param name="mailFolderFullName">Full name of the mail folder to connect to.</param>
/// <param name="cancellationToken">Request cancellation token.</param>
/// <returns>Connected <see cref="IMailFolder"/>.</returns>
ValueTask<IMailFolder> GetMailFolderAsync(string mailFolderFullName, CancellationToken cancellationToken = default);

/// <summary>
/// Asynchronously move the specified message to the Sent folder.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,15 @@ public interface IMailFolderClient : IAsyncDisposable, IDisposable
/// <returns><see cref="UniqueId"/> of the moved message.</returns>
Task<UniqueId?> MoveToAsync(IMessageSummary messageSummary, SpecialFolder mailFolder = SpecialFolder.Sent, CancellationToken cancellationToken = default);

/// <summary>
/// Asynchronously move the specified message to the specified folder.
/// </summary>
/// <param name="messageSummary">Source <see cref="IMailFolder"/> and <see cref="UniqueId"/>.</param>
/// <param name="destinationFolder">Name of the destination mail folder.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns><see cref="UniqueId"/> of the moved message.</returns>
Task<UniqueId?> MoveToAsync(IMessageSummary messageSummary, string destinationFolder, CancellationToken cancellationToken = default);

/// <summary>
/// Asynchronously copy the specified message to the specified folder.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -391,13 +391,15 @@ public static async Task AddFlagsAsync(this IMessageSummary messageSummary, Mess

/// <summary>
/// Move the message to the specified folder.
/// Warning: if the message is from a folder that is still being monitored,
/// Warning: Do not use this method with the MailFolderMonitor.
/// If the message is from a folder that is still being monitored,
/// then accessing that folder here is likely to conflict with the monitoring.
/// </summary>
/// <param name="messageSummary"><see cref="IMessageSummary"/> body to download.</param>
/// <param name="destination">Destination mail folder.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns><see cref="UniqueId"/> in the <see cref="IMailFolder"/> destination, or null.</returns>
[Obsolete("This causes issues when used with MailFolderMonitor. Use MailFolderClient.MoveToAsync instead.")]
public static async Task<UniqueId?> MoveToAsync(this IMessageSummary messageSummary, IMailFolder destination, CancellationToken cancellationToken = default)
{
UniqueId? resultUid = null;
Expand Down
13 changes: 1 addition & 12 deletions source/MailKitSimplified.Receiver/Services/ImapReceiver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ namespace MailKitSimplified.Receiver.Services
/// <inheritdoc cref="IImapReceiver" />
public sealed class ImapReceiver : IImapReceiver
{
private readonly IMailFolderCache _mailFolderCache;

private Lazy<MailFolderClient> _mailFolderClient;
private Lazy<MailFolderReader> _mailFolderReader;
private Lazy<MailFolderMonitor> _mailFolderMonitor;
Expand All @@ -32,7 +30,7 @@ public sealed class ImapReceiver : IImapReceiver
private EmailReceiverOptions _receiverOptions;

/// <inheritdoc cref="IImapReceiver" />
public ImapReceiver(IOptions<EmailReceiverOptions> receiverOptions, ILogger<ImapReceiver> logger = null, IProtocolLogger protocolLogger = null, IImapClient imapClient = null, ILoggerFactory loggerFactory = null, IMailFolderCache mailFolderCache = null)
public ImapReceiver(IOptions<EmailReceiverOptions> receiverOptions, ILogger<ImapReceiver> logger = null, IProtocolLogger protocolLogger = null, IImapClient imapClient = null, ILoggerFactory loggerFactory = null)
{
_loggerFactory = loggerFactory ?? NullLoggerFactory.Instance;
_logger = logger ?? _loggerFactory.CreateLogger<ImapReceiver>();
Expand All @@ -41,7 +39,6 @@ public ImapReceiver(IOptions<EmailReceiverOptions> receiverOptions, ILogger<Imap
SetProtocolLog(protocolLogger);
else
SetImapClient(imapClient);
_mailFolderCache = mailFolderCache;
}

public static ImapReceiver Create(string imapHost, ushort imapPort = 0, string username = null, string password = null, string mailFolderName = null, string protocolLog = null, bool protocolLogFileAppend = false, ILogger<ImapReceiver> logger = null, IProtocolLogger protocolLogger = null, IImapClient imapClient = null, ILoggerFactory loggerFactory = null)
Expand Down Expand Up @@ -289,14 +286,6 @@ internal async ValueTask AuthenticateImapClientAsync(CancellationToken cancellat
}
}

/// <inheritdoc cref="ImapClient.GetFolderAsync"/>
public async ValueTask<IMailFolder> GetMailFolderAsync(string mailFolderFullName, CancellationToken cancellationToken = default)
{
if (_mailFolderCache == null)
return null;
return await _mailFolderCache.GetMailFolderAsync(Clone(), mailFolderFullName, cancellationToken).ConfigureAwait(false);
}

/// <inheritdoc cref="ImapClient.GetFolderAsync"/>
public async ValueTask<IMailFolder> ConnectMailFolderAsync(CancellationToken cancellationToken = default)
{
Expand Down
18 changes: 17 additions & 1 deletion source/MailKitSimplified.Receiver/Services/MailFolderClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,16 @@ public sealed class MailFolderClient : IMailFolderClient
private ILogger _logger;
private IMailFolder _mailFolder = null;
private IList<string> SentFolderNames;
private readonly IMailFolderCache _mailFolderCache;
private readonly IList<string> DraftsFolderNames;
private readonly IList<string> JunkFolderNames;
private readonly IList<string> TrashFolderNames;
private readonly IImapReceiver _imapReceiver;

public MailFolderClient(IImapReceiver imapReceiver, IOptions<FolderClientOptions> options = null, ILogger<MailFolderClient> logger = null)
public MailFolderClient(IImapReceiver imapReceiver, IOptions<FolderClientOptions> options = null, ILogger<MailFolderClient> logger = null, IMailFolderCache mailFolderCache = null)
{
_logger = logger ?? NullLogger<MailFolderClient>.Instance;
_mailFolderCache = mailFolderCache;
_imapReceiver = imapReceiver ?? throw new ArgumentNullException(nameof(imapReceiver));
SentFolderNames = options?.Value?.SentFolderNames ?? FolderClientOptions.CommonSentFolderNames;
DraftsFolderNames = options?.Value?.DraftsFolderNames ?? FolderClientOptions.CommonDraftsFolderNames;
Expand Down Expand Up @@ -293,6 +295,20 @@ public async Task<int> DeleteMessagesAsync(TimeSpan relativeOffset, SearchQuery
public async Task<UniqueId?> MoveToAsync(IMessageSummary messageSummary, SpecialFolder mailFolder = SpecialFolder.Sent, CancellationToken cancellationToken = default) =>
await MoveOrCopyAsync(messageSummary.UniqueId, messageSummary.Folder, GetFolder(mailFolder).Value, move: true, cancellationToken).ConfigureAwait(false);

public async Task<UniqueId?> MoveToAsync(IMessageSummary messageSummary, string destinationFolderFullName, CancellationToken cancellationToken = default)
{
UniqueId? result;
if (_mailFolderCache == null)
result = await MoveOrCopyAsync(messageSummary.UniqueId, destinationFolderFullName, move: true, cancellationToken).ConfigureAwait(false);
else
{
var sourceFolder = await _mailFolderCache.GetMailFolderAsync(_imapReceiver, messageSummary.Folder.FullName, cancellationToken).ConfigureAwait(false);
var destinationFolder = await _mailFolderCache.GetMailFolderAsync(_imapReceiver, destinationFolderFullName, cancellationToken).ConfigureAwait(false);
result = await MoveOrCopyAsync(messageSummary.UniqueId, sourceFolder, destinationFolder, move: true, cancellationToken).ConfigureAwait(false);
}
return result;
}

internal async Task<UniqueId?> MoveOrCopyAsync(UniqueId messageUid, IMailFolder source, IMailFolder destination, bool move = true, CancellationToken cancellationToken = default)
{
UniqueId? resultUid = null;
Expand Down

0 comments on commit 256569b

Please sign in to comment.