diff --git a/Src/SmtpServer/ISessionServiceProviderFactory.cs b/Src/SmtpServer/ISessionServiceProviderFactory.cs
new file mode 100644
index 0000000..aeb7ae0
--- /dev/null
+++ b/Src/SmtpServer/ISessionServiceProviderFactory.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Threading.Tasks;
+
+namespace SmtpServer
+{
+ ///
+ /// Allows customization of the IServiceProvider instance that is used in the session context.
+ ///
+ public interface ISessionServiceProviderFactory
+ {
+ ///
+ /// Creates an IServiceProvider instance for one session context.
+ ///
+ IServiceProvider CreateServiceProvider(IServiceProvider rootServiceProvider);
+ }
+}
diff --git a/Src/SmtpServer/Net/IEndpointListener.cs b/Src/SmtpServer/Net/IEndpointListener.cs
index 11a287b..ef3b958 100644
--- a/Src/SmtpServer/Net/IEndpointListener.cs
+++ b/Src/SmtpServer/Net/IEndpointListener.cs
@@ -11,7 +11,7 @@ namespace SmtpServer.Net
public interface IEndpointListener : IDisposable
{
///
- /// Returns a securtable pipe to the endpoint.
+ /// Returns a securable pipe to the endpoint.
///
/// The session context that the pipe is being created for.
/// The cancellation token.
diff --git a/Src/SmtpServer/SmtpServer.cs b/Src/SmtpServer/SmtpServer.cs
index d4c4a75..686819e 100644
--- a/Src/SmtpServer/SmtpServer.cs
+++ b/Src/SmtpServer/SmtpServer.cs
@@ -35,6 +35,7 @@ public class SmtpServer
readonly ISmtpServerOptions _options;
readonly IServiceProvider _serviceProvider;
readonly IEndpointListenerFactory _endpointListenerFactory;
+ readonly ISessionServiceProviderFactory _sessionServiceProviderFactory;
readonly SmtpSessionManager _sessions;
readonly CancellationTokenSource _shutdownTokenSource = new CancellationTokenSource();
readonly TaskCompletionSource _shutdownTask = new TaskCompletionSource();
@@ -50,6 +51,7 @@ public SmtpServer(ISmtpServerOptions options, IServiceProvider serviceProvider)
_serviceProvider = serviceProvider;
_sessions = new SmtpSessionManager(this);
_endpointListenerFactory = serviceProvider.GetServiceOrDefault(EndpointListenerFactory.Default);
+ _sessionServiceProviderFactory = serviceProvider.GetServiceOrDefault(null);
}
///
@@ -128,7 +130,8 @@ async Task ListenAsync(IEndpointDefinition endpointDefinition, CancellationToken
while (cancellationTokenSource.Token.IsCancellationRequested == false)
{
- var sessionContext = new SmtpSessionContext(_serviceProvider, _options, endpointDefinition);
+ var spForCtx = _sessionServiceProviderFactory?.CreateServiceProvider(_serviceProvider);
+ var sessionContext = new SmtpSessionContext(spForCtx ?? _serviceProvider, _options, endpointDefinition);
try
{
@@ -144,7 +147,7 @@ async Task ListenAsync(IEndpointDefinition endpointDefinition, CancellationToken
if (sessionContext.Pipe != null)
{
- _sessions.Run(sessionContext, cancellationTokenSource.Token);
+ _sessions.Run(sessionContext, cancellationTokenSource.Token, spForCtx);
}
}
}
diff --git a/Src/SmtpServer/SmtpSessionManager.cs b/Src/SmtpServer/SmtpSessionManager.cs
index d490028..e5f462b 100644
--- a/Src/SmtpServer/SmtpSessionManager.cs
+++ b/Src/SmtpServer/SmtpSessionManager.cs
@@ -16,9 +16,9 @@ internal SmtpSessionManager(SmtpServer smtpServer)
_smtpServer = smtpServer;
}
- internal void Run(SmtpSessionContext sessionContext, CancellationToken cancellationToken)
+ internal void Run(SmtpSessionContext sessionContext, CancellationToken cancellationToken, IServiceProvider sessionServiceProvider)
{
- var handle = new SmtpSessionHandle(new SmtpSession(sessionContext), sessionContext);
+ var handle = new SmtpSessionHandle(new SmtpSession(sessionContext), sessionContext, sessionServiceProvider);
Add(handle);
handle.CompletionTask = RunAsync(handle, cancellationToken).ContinueWith(task =>
@@ -27,7 +27,7 @@ internal void Run(SmtpSessionContext sessionContext, CancellationToken cancellat
});
}
- async Task RunAsync(SmtpSessionHandle handle, CancellationToken cancellationToken)
+ private async Task RunAsync(SmtpSessionHandle handle, CancellationToken cancellationToken)
{
using var sessionTimeoutCancellationTokenSource = new CancellationTokenSource(handle.SessionContext.EndpointDefinition.SessionTimeout);
@@ -58,6 +58,15 @@ async Task RunAsync(SmtpSessionHandle handle, CancellationToken cancellationToke
await handle.SessionContext.Pipe.Input.CompleteAsync();
handle.SessionContext.Pipe.Dispose();
+
+ if (handle.SessionServiceProvider is IAsyncDisposable asyncDisposable)
+ {
+ await asyncDisposable.DisposeAsync();
+ }
+ else if (handle.SessionServiceProvider is IDisposable disposable)
+ {
+ disposable.Dispose();
+ }
}
}
@@ -91,16 +100,19 @@ void Remove(SmtpSessionHandle handle)
class SmtpSessionHandle
{
- public SmtpSessionHandle(SmtpSession session, SmtpSessionContext sessionContext)
+ public SmtpSessionHandle(SmtpSession session, SmtpSessionContext sessionContext, IServiceProvider sessionServiceProvider)
{
Session = session;
SessionContext = sessionContext;
+ SessionServiceProvider = sessionServiceProvider;
}
public SmtpSession Session { get; }
public SmtpSessionContext SessionContext { get; }
+ public IServiceProvider SessionServiceProvider { get; }
+
public Task CompletionTask { get; set; }
}
}