BT

New Early adopter or innovator? InfoQ has been working on some new features for you. Learn more

MailKit Officially Replaces .NET’s SmtpClient

| by Jonathan Allen Follow 6 Followers on Apr 14, 2017. Estimated reading time: 2 minutes |

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 Stage
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.

Tell us what you think

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

Email me replies to any of my messages in this thread

Most likely a false alarm by Tudor Turcu

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

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

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

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.

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

Email me replies to any of my messages in this thread

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

Email me replies to any of my messages in this thread

4 Discuss

Login to InfoQ to interact with what matters most to you.


Recover your password...

Follow

Follow your favorite topics and editors

Quick overview of most important highlights in the industry and on the site.

Like

More signal, less noise

Build your own feed by choosing topics you want to read about and editors you want to hear from.

Notifications

Stay up-to-date

Set up your notifications and don't miss out on content that matters to you

BT