これから始めるSpring.NET その4

前回 では、フォームをDI コンテナに登録し、それを取り出して表示しました。今回はもう少し踏み込んでみます。

まずはMainFormクラスのUIを以下のように変更します。

MainForm.cs

テキストボックスをMultiline=true で貼り付け、[File] → [Save] というメニューを作りました。
見た通りの簡単なテキストエディタです。これにいくつかの機能を実装していきます。

[File] → [Save] というメニューを作ったので、テキストボックスに入力した内容をファイルに保存する機能を作ります。

この程度の機能ならば、フォームのイベントハンドラに直接書いてしまってもいいくらいですが、それでは意味が無い*1のでファイルを保存する機能を持つクラスを定義します。

ContentsManager.cs
using System;
using System.IO;
using System.Text;
using System.Diagnostics;

namespace SpringSample.IO {
    public class ContentsManager : IContentsManager {
        public ContentsManager() { }

        public void Save(string contents, string fileName) {
            using(var sw = new StreamWriter(fileName, false, Encoding.Default)) {
                sw.Write(contents);
            }
        }
    }
    
    public interface IContentsManager {
        void Save(string contents, string fileName);
    }
}

ContentsManagerというクラスを定義しました。このクラスは、指定した内容を指定したファイル名で保存するSaveメソッドを持っています。また、このクラスのpublicなメソッドはIContentsManagerインターフェースに分離しておきます。

このクラスを使うために、MainFormクラスに以下のフィールドとプロパティを追加します。

MainForm.cs
private IContentsManager contentsManager;
/// <summary>
/// コンテンツ管理オブジェクトを設定します。
/// </summary>
public IContentsManager ContentsManager {
    private get { return contentsManager; }
    set { contentsManager = value; }
}

あとは、[File]メニューにClickイベントハンドラを追加して、そこに以下のコードを記述します。

MainForm.cs
/// <summary>
/// [File] → [Save]メニューが選択された時
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void mnuFileSave_Click(object sender, EventArgs e) {
    string fileName;

    using(var saveFileDlg = new SaveFileDialog()) {
        saveFileDlg.Filter = "(*.txt)|*.txt";
        saveFileDlg.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);

        if((saveFileDlg.ShowDialog(this)) == DialogResult.Cancel) return;

        fileName = saveFileDlg.FileName;
    }
    ContentsManager.Save(txtContent.Text, fileName);
}

ファイルの保存ダイアログを表示し、ダイアログで選択したファイル名とテキストボックスに入力された内容でContentsManager.Saveメソッドを呼び出しています。

もちろんこのままF5でアプリケーションを開始しても、正常には動作しない*2ので、オブジェクト定義ファイルを以下のように変更します。

objects.config
<?xml version="1.0" encoding="utf-8" ?>
<objects xmlns="http://www.springframework.net">

    <object name="mainForm" type="SpringSample.MainForm, SpringSample">
        <property name="ContentsManager" ref="contentsManager" />
    </object>

    <object name="contentsManager" type="SpringSample.IO.ContentsManager, SpringSample" />
    
</objects>

新しくcontentsManagerというobject定義を追加しています。このオブジェクトをmainFormのContentsManagerプロパティにインジェクションするために、ref属性を使っています。

ref属性
参照するオブジェクトのオブジェクト名を指定します。

また、これは以下のように記述することもできます。

objects.config
<?xml version="1.0" encoding="utf-8" ?>
<objects xmlns="http://www.springframework.net">

    <object name="mainForm" type="SpringSample.MainForm, SpringSample">
        <property name="ContentsManager">
            <object type="SpringSample.IO.ContentsManager, SpringSample" />
        </property>
    </object>
        
</objects>

contentsManagerというobject定義を追加せずに、mainFormのContentsManagerプロパティの中でname属性を指定しない無名のオブジェクトとして設定しています。感覚的にはローカル変数に近いです。
オブジェクトを使い回さない場合は、このように設定するほうが見通しがよくなるのでお勧めします。

これで正常にプログラムが動作します。

*1:Dependency Injection が目的ですから

*2:ContentsManager.Save のところでNullReferenceExceptionが出ます