BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース MailKitが公式に.NETのSmtpClientを置き換えることを明らかにした。

MailKitが公式に.NETのSmtpClientを置き換えることを明らかにした。

原文(投稿日:2017/04/14)へのリンク

MicrosoftがSmtpClientをオープンソースライブラリに置き換えることを明らかにした。SmtpClientのドキュメントには、「廃止予定(SmtpClientとそのタイプのネットワークは設計が不十分であり、代わりに https://github.com/jstedfast/MailKit と https://github.com/jstedfast/MimeKit を使うことを強く推奨する)」と書かれている。

MailKitMimeKitは、Jeffrey Stedfast氏によって作成されたライブラリだ。InfoQは2014年に、彼にインタビューした。その当時も、MailKitとMimeKitは、.NETのもっとも包括的なMIMEとメールのライブラリだとみなされていた。

Microsoftが最初に受け入れたオープンソースライブラリは、NewtonsoftのJSON.NETだった。これはASP.NET WebAPIで広く使われており、JavaScriptSerializerクラスの代替として公式に推奨され、一般的にDataContractJsonSerializerクラスよりも好まれている。ただし、SmtpClientとは違って、どちらのクラスも「廃止予定(obsolete)」にはなっていない。

SmtpClientの一番の問題は、接続ライフサイクルがわかりにくいことだ。SMTPサーバーへの接続には時間がかかる可能性がある。認証が有効な場合は特にそうだ。そのため、各SmtpClientオブジェクトは内部接続プールを持っている。

これはかなり奇妙な設計だ。よくあるデータベース接続の場合を考えてみよう。SqlClientでDisposeを呼び出すと、その接続はプールに戻される。そして、新しいSqlClientを作成するときには、同じ接続文字列をもつアクティブな接続がないか、プールをチェックするようになっている。

SmtpClientの場合、Disposeを呼び出すと、全ての接続がクローズされ、そのオブジェクトの接続プールは廃棄されてしまう。つまり、通常の‘using’ブロックパターンでは使えないのだ。

HttpClientみたいな一つの共有インスタンスを持てばいい」と思うかもしれない。でも、だめだ。HttpClientと違って、Send/SendAsyncメソッドはスレッドセーフではない。そのため、独自の同期スキームを導入しない限り、そのような使い方はできない。実際、SmtpClientのドキュメントはこう警告している。

いつアプリケーションがSmtpClientオブジェクトを使うのをやめて、クリーンナップすべきかを判断するすべはありません。

これに対して、MailKitのSMTPクライアントは、一つのサーバーに対する単純な接続を表現している。内部接続プールによる複雑さはなく、アプリケーション固有のMailKit接続オブジェクト用プールを簡単に作ることができる。

アクティブなバグの数は驚くほど少ないが、MailKitには真の非同期サポートという問題がある。既存のライブラリに非同期サポートを追加する場合、メソッドをすべてコピーして、非同期サポートに必要な変更を少し加えるというやり方がよくとられる。こうしたコードの重複は、シンプルなアプリケーションの場合はそう厄介ではないが、メールクライアントのような複雑なアプリケーションの場合には、悪夢のようなメンテナンスに陥るおそれがある。そのため、彼らはとりあえず、同期コードパスを呼び出してスレッドをブロックすることで、非同期サポートをシミュレートしている。

この問題をどうするかは決まっていないが、検討すべき選択肢の一つは、AsyncRewriterツールだ。このRoslynベースのツールは、PostgreSQLチームが同期コードを同等の非同期コードに変換するのに使われている。

Rate this Article

Relevance
Style

この記事に星をつける

おすすめ度
スタイル

BT