This release contains a BREAKING CHANGE refactor of the email client surface:
IEmailClienthas been refactored into a generic base interfaceIEmailClient<TRequest, TResponse>that defines a common contract for both single and batch email clients.- Two specialized interfaces were introduced:
ISendEmailClient— for single-send (SendEmailRequest/SendEmailResponse).IBatchEmailClient— for batch sends (BatchEmailRequest/BatchEmailResponse).
IMailtrapClientemail entry points changed:Email(),Test(),Bulk(),Transactional()now returnISendEmailClient.- New methods
BatchEmail(),BatchTest(),BatchBulk(),BatchTransactional()returnIBatchEmailClient.
The split clarifies single-send vs batch-send behavior and request/response types, enabling stronger typing and a clearer API surface for bulk operations.
-
BC BREAK: The
IEmailClientinterface has been refactored into a generic base interface to unify all email sending operations.It now defines a common contract for both single and batch email clients.
public interface IEmailClient<TRequest, TResponse> where TRequest : class where TResponse : class { Task<TResponse> Send(TRequest request, CancellationToken cancellationToken = default); }
Before (v2.x):
public interface IEmailClient { Task<SendEmailResponse> Send(SendEmailRequest request); }
After (v3.0):
public interface ISendEmailClient : IEmailClient<SendEmailRequest, SendEmailResponse> { } public interface IBatchEmailClient : IEmailClient<BatchEmailRequest, BatchEmailResponse> { }
Migration note: Replace direct usages of
IEmailClientwithISendEmailClientorIBatchEmailClientas appropriate.
-
BC BREAK: Methods in
IMailtrapClientthat previously returnedIEmailClientnow returnISendEmailClient.Email()Transactional()Bulk()Test(long inboxId)
Before (v2.x):
IMailtrapClient client = new MailtrapClient(apiKey); IEmailClient emailClient = client.Email(); await emailClient.Send(new SendEmailRequest());
After (v3.0):
IMailtrapClient client = new MailtrapClient(apiKey); ISendEmailClient sendClient = client.Email(); await sendClient.Send(new SendEmailRequest());
-
NEW: Introduced dedicated batch email methods returning
IBatchEmailClient.Method Description BatchEmail()Returns a default batch email client based on configuration. BatchTransactional()Returns a client for sending batch transactional emails. BatchBulk()Returns a client for sending batch bulk emails. BatchTest(long inboxId)Returns a client for sending batch test emails. Example:
IBatchEmailClient batchClient = client.BatchEmail(); await batchClient.Send(new BatchEmailRequest { Base = EmailRequest.Create() { ... }, Requests = new List<SendEmailRequest> { ... } });
-
NEW: Added
BatchEmailRequestBuilder— a fluent helper for constructing batch email requests. Similar in design to existing builders:EmailRequestBuilderandSendEmailRequestBuilder.Example:
using Mailtrap.Emails.Requests; var batchRequest = BatchEmailRequest .Create() .Base(b => b .From("sender@example.com") .Subject("Greetings")) .Requests( r => r.To("user1@example.com").Html("<p>Hello User 1!</p>") ); await client.BatchEmail().Send(batchRequest);
| Area | Change | Type |
|---|---|---|
IEmailClient |
Refactored into generic base interface IEmailClient<TRequest, TResponse> |
BC BREAK |
ISendEmailClient |
New interface for single email sending | New |
IBatchEmailClient |
New interface for batch email sending | New |
IMailtrapClient.Email(), Transactional(), etc. |
Now return ISendEmailClient |
BC BREAK |
IMailtrapClient batch methods |
Added BatchEmail(), BatchTransactional(), BatchBulk(), BatchTest() |
New |
BatchEmailRequestBuilder |
Fluent builder for batch requests | New |
Before (v2.x):
// Example using old IEmailClient directly
IMailtrapClient client = new MailtrapClient(apiKey);
IEmailClient emailClient = client.Email();
await emailClient.Send(new SendEmailRequest
{
To = new List<string> { "user@example.com" },
Subject = "Welcome!",
Html = "<p>Hello!</p>"
});After (v3.0): Prefer the specialized interface
var client = new MailtrapClient(apiKey);
// Single email
var sendClient = client.Email(); // Transactional(), Bulk(), Test() -> ISendEmailClient
await sendClient.Send(new SendEmailRequest
{
To = new List<string> { "user@example.com" },
Subject = "Welcome!",
Html = "<p>Hello!</p>"
});
// Batch email
var batchRequest = BatchEmailRequest
.Create()
.Requests(
r => r.To("user@example.com").Subject("Welcome on board")
);
await client
.BatchEmail() // BatchTransactional(), BatchBulk(), BatchTest() -> IBatchEmailClient
.Send(batchRequest);-
Modify implementations to implement the new specialized interfaces:
- Single-send implementation:
public class MySendEmailClient : ISendEmailClient { ... }
- Batch-send implementation:
public class MyBatchEmailClient : IBatchEmailClient { ... }
- Single-send implementation:
-
Update dependency injection registrations to register the new interfaces:
- Example (Microsoft DI):
services.AddSingleton<ISendEmailClient, MySendEmailClient>(); services.AddSingleton<IBatchEmailClient, MyBatchEmailClient>();
- Example (Microsoft DI):
-
If you registered or resolved the generic
IEmailClient<...>at runtime, replace those registrations/resolutions with the specialized interfaces.
-
CS0311 or generic constraint errors referencing
IEmailClient<TRequest,TResponse>:- Cause: code still references the old generic type or a wrong generic constraint.
- Fix: replace references with
ISendEmailClientorIBatchEmailClient, and update any generic constraints to match the new interfaces.
-
"Missing method" or "method does not exist" errors for batch methods:
- Cause: using
Email()/Bulk()/Transactional()/Test()where a batch operation was intended. - Fix: switch to the new
BatchEmail()/BatchBulk()/BatchTransactional()/BatchTest()methods which returnIBatchEmailClient.
- Cause: using
-
Test/mocking failures due to interface changes:
- Cause: mocks/stubs implement the old
IEmailClienttype. - Fix: update mocks to implement
ISendEmailClientorIBatchEmailClient. Example (Moq):var mockSend = new Mock<ISendEmailClient>(); var mockBatch = new Mock<IBatchEmailClient>();
- Cause: mocks/stubs implement the old
-
DI resolution errors (unable to resolve service):
- Cause: DI registration still targets the old generic interface.
- Fix: register the concrete implementation under
ISendEmailClient/IBatchEmailClientas needed.
- Update NuGet package to 3.0.0 (or the appropriate prerelease).
- Search codebase for
IEmailClientand replace with eitherISendEmailClientorIBatchEmailClient. - Replace usages of batch sends that used
Email()/Bulk()/Transactional()/Test()with the new Batch* methods. - Update DI registrations & factories to return the new interfaces.
- Use
BatchEmailRequestBuilderfor building batch requests. - Test all email sending paths (single and batch) after migration.
Runtime behavior is unchanged for single sends; This refactor improves SDK consistency, providing a clear separation between single and batch email operations while maintaining a unified interface structure for future extensibility.