BT

InfoQ Homepage News MailKit Officially Replaces .NET’s SmtpClient

MailKit Officially Replaces .NET’s SmtpClient

Bookmarks

For the second time, Microsoft has officially marked a .NET class as being replaced by an open source library. The documentation for SmtpClient now reads, “Obsolete("SmtpClient and its network of types are poorly designed, we strongly recommend you use https://github.com/jstedfast/MailKit and https://github.com/jstedfast/MimeKit instead")”.

MailKit and MimeKit were created by Jeffrey Stedfast, who we interviewed in 2014. Even back then they were considered to be the most comprehensive MIME and email libraries for .NET.

The first major open source library that Microsoft embraced was Newtonsoft’s JSON.NET. Used extensively in ASP.NET WebAPI, this is officially recommended in lieu of the JavaScriptSerializer class and is generally preferred over the DataContractJsonSerializer class as well. Unlike SmtpClient, neither of these classes are marked as obsolete.

The main problem with SmtpClient is that it has a confusing connection lifecycle. Connecting to a SMTP server can be time consuming, especially if authentication is enabled, so each SmtpClient object has an internal connection pool.

This is a rather strange design. Consider for a moment a typical database connection. When you call Dispose on a SqlClient, the underlying connection is returned to the pool. When you create a new SqlClient, the pool is checked for an active connection with the same connection string.

With SmtpClient, calling Dispose closes all of the connections and drains that object’s connection pool. This means you can’t use it with the typical ‘using’ block pattern.

You may be thinking, “So I just hold onto one shared instance like HttpClient”. Well, no. Unlike HttpClient, the Send/SendAsync methods are not thread thread-safe. So unless you want to introduce your own synchronization scheme, you can’t use it that way either. In fact, the documentation for SmtpClient warns,

There is no way to determine when an application is finished using the SmtpClient object and it should be cleaned up.

By contrast, the SMTP client in MailKit represents a simple connection to a single server. By eliminating the complexity caused by internal connection pools, it actually makes it easier to create an application-specific pool for MailKit’s connection object.

While the active bug count is surprisingly low, one area where MailKit does have problems is true async support. The normal way to add async to an existing library is to copy all of the methods, making the small changes needed for asynchronous support. This code duplication isn’t hard to deal with in simple applications, but for something as complicated as an email client it could become a maintenance nightmare. So for the time being they are simulating async support by simply calling the synchronous code paths and blocking threads.

No decision has been made about how to deal with this, but one option being considered is the AsyncRewriter tool. This Roslyn based tool was used by the PostgreSQL team to convert their synchronous code into asynchronous equivalents.

Rate this Article

Adoption
Style

Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Community comments

  • Most likely a false alarm

    by Tudor Turcu /

    Your message is awaiting moderation. Thank you for participating in the discussion.

    github.com/dotnet/docs/issues/1876 'System.Net.Mail.SmtpClient is marked as obsolete in docs, but not in the source code'

  • Too fast a bit, maybe require some checking

    by Michał Brix /

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Gentlemans, maybe some information about that:
    github.com/dotnet/docs/issues/1876
    whould be also important to add or update or reference in article.

  • Re: Most likely a false alarm

    by Jonathan Allen /

    Your message is awaiting moderation. Thank you for participating in the discussion.

    We're still watching that bug report, at this time they haven't offered an official retraction or explanation. So saying definitively that it was a mistake would just be conjecture on our part.

  • Article is misleading

    by Rob Smith /

    Your message is awaiting moderation. Thank you for participating in the discussion.

    SmtpClient is not being deprecated in .NET. This is a byproduct of a bug in the way the docs are generated: github.com/dotnet/docs/issues/1876#issuecomment...
    which points to
    github.com/mono/api-doc-tools/issues/76

    The Mono implementation marked SmtpClient obsolete and since Xamarin assemblies are aggregated from a doc standpoint, the annotation is incorrectly displaying for all doc types.

    The issues with .NET's SmtpClient are still points to keep in mind as disposal does send the QUIT message across all established connections.

  • Re: Article is misleading

    by Jonathan Allen /

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Five months later and it still hasn't been changed.

  • Re: Article is misleading

    by Jonathan Allen /

    Your message is awaiting moderation. Thank you for participating in the discussion.

    As of October 25, the official documentation has been changed and Microsoft is no longer marking SMTPClient as obsolete.

    However, it is still fundamentally broken and shouldn't be used for production applications where alternatives exist.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

BT

Is your profile up-to-date? Please take a moment to review and update.

Note: If updating/changing your email, a validation request will be sent

Company name:
Company role:
Company size:
Country/Zone:
State/Province/Region:
You will be sent an email to validate the new email address. This pop-up will close itself in a few moments.