.NETで作る!

.NETに関するあれこれ(C#、VB.NET)

Unity+app.configでSendMail

Unityシリーズ第3弾。Unityを使ってメールを飛ばしてみましょう。

前準備

Nugetから「Unity」と「CommonServiceLocator」をインストール。

Unityを使用しない場合

比較対象のため、まずUnityを使用しない場合のコードを先に挙げておきます。

Dim message As New MailMessage(
    "from@gmail.com",
    "to1@gmail.com, to2@gmail.com",
    "subject text",
    "body text")
Dim client As New SmtpClient("smtp.gmail.com")
client.Credentials = New NetworkCredential("from@gmail.com", "*****")
client.EnableSsl = True
client.Port = 587
client.Send(message)

Unityを使用する場合

VB

定数はapp.configで管理されるため、VBコンパイルされる)側には代入式は無くなります。

'Imports Microsoft.Practices.ServiceLocation
'Imports Microsoft.Practices.Unity
'Imports Microsoft.Practices.Unity.Configuration

'スタートアップ時のイベントで初期化(決まり文句)
Dim container As New UnityContainer
container.LoadConfiguration()

Dim service As New UnityServiceLocator(container)
ServiceLocator.SetLocatorProvider(Function() service)
'Imports System.Net
'Imports System.Net.Mail
'Imports Microsoft.Practices.ServiceLocation
'Imports Microsoft.Practices.Unity
'Imports Microsoft.Practices.Unity.Configuration

Dim message = ServiceLocator.Current.GetInstance(Of MailMessage)()
Dim client = ServiceLocator.Current.GetInstance(Of SmtpClient)()
client.Send(message)

app.config

Unityを使う上での決まり文句を書いてから…

  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>
  </configSections>

依存関係を定義。

  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    
    <alias alias="SmtpClient" type="System.Net.Mail.SmtpClient, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    <alias alias="MailMessage" type="System.Net.Mail.MailMessage, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    <alias alias="NetworkCredential" type="System.Net.NetworkCredential, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    
    <container>
      
      <register type="NetworkCredential" mapTo="NetworkCredential" name="SmtpCredential" >
        <lifetime type="singleton" />
        <constructor>
          <param name="userName" value="from@gmail.com" />
          <param name="password" value="*****" />
        </constructor> 
      </register>
      
      <register type="SmtpClient" mapTo="SmtpClient" >
        <lifetime type="singleton" />
        <constructor>
          <param name="host" value="smtp.gmail.com" />
          <param name="port" value="587" />
        </constructor>
        <property name="EnableSsl" value="True"/>
        <property name="Credentials">
          <dependency type="NetworkCredential" name="SmtpCredential" />
        </property>
      </register>   
      
      <register type="MailMessage" mapTo="MailMessage" >
        <constructor>
          <param name="from" value="from@gmail.comm" />
          <param name="to" value="user1@gmail.com, user2@gmail.com" />
          <param name="subject" value="Hello, Unity" />
          <param name="body" value="Hello, Unity!!" />
        </constructor>
      </register>

    </container>
  </unity>

基本は前にやったことと同じですが、今回はオブジェクトの代入をしているのが新しいところ。 具体的にはここ。

        <property name="Credentials">
          <dependency type="NetworkCredential" name="SmtpCredential" />
        </property>

とは言っても代入するインスタンスの定義の仕方は従来通りなので…

      <register type="NetworkCredential" mapTo="NetworkCredential" name="SmtpCredential" >
        <lifetime type="singleton" />
        <constructor>
          <param name="userName" value="from@gmail.com" />
          <param name="password" value="*****" />
        </constructor> 
      </register>

特に難しいこともなし。 素晴らしいね!

Unityだけでできないと思われること

CC、Bccの代入はたぶん無理。理由は同プロパティがReadOnlyのコレクションだから。 Unityでメソッドも制御できるらしいのでやろうとしてみたけどうまくいかず。

        <!--動きません-->
        <property name="CC">
          <method name="Add">
            <param name="addresses" name="user1@gmail.com" />
          </method>
        </property>

propertyの子要素にmethodは許可されていない模様。 それなら拡張メソッドでMailMessage直下に「AddCC」みたいなメソッドを作ったらどうなるか試してみました(すでにUnityだけで表現できてない)が、こちらは「MailMessageクラスにAddCCメソッドなんてないよ」と例外が出ます。

どうしてもやりたいんなら、MailMessageのラッパークラスを作るしかないですね。

ちなみに添付ファイルもReadOnlyのコレクションだから多分無理。

メモ書き

d.hatena.ne.jp

今回は使わなかったけど、TypeConverterを使うと動的な値代入もできるらしい。

. .