日記じゃねーど

2007/02/21(水)

S2Container.NETを使ってみた。
------------------------------------
流行りのDIコンテナなるものを使ってみました。
和製DIコンテナ、その名もSeaserという名前です。
Javaプロジェクトなんですが、.NetFrameworkの移植版もあるので今回はそれを使用します。



■概要
簡単なプログラミングでDIコンテナを試します。

用意するのは

http://s2container.net.seasar.org/ja/index.html

上記URLからS2Container.NET 1.2.8 をダウンロードしましょう。現在、1.2.8というバージョンになっています。

それからダイナミックリンクライブラリーを2つと実行ファイルを1つ、
それからアプリケーション構成ファイルというのと
DICONファイル(ダイコンと呼ぶらしいです)をつくります。

これだけ用意すればDIコンテナを試す事ができます。



■手順
下記でメッセージを出力するプログラムを作成します。インターフェースでShoMessageメソッドを用意しておき、それを実装するクラスを作成します。また、Testとしてそれを実行するクラスも作成します。

1.S2Container.NET 1.2.8をダウンロードし解凍しておきましょう。
  場所は後からVisualStudio上から参照設定が必要になるため、
  わかりやすい所に置いておきましょう。


2.メッセージを出力するインターフェイスを作成

  クラスライブラリのプロジェクトを作成します。
  名前は「Art.IHello」にしました。
  

  コード(IHello.cs)は下記のとおりです。

using System;
using System.Collections.Generic;
using System.Text;

namespace Art
{
    public interface IHello
    {
        void ShowMessage(string msg);
    }
}

  ものすごく簡単です。
  ちゃんとビルドしてますよね??

3.手順2で作ったインターフェースの実装を作成します。
  当然、先ほど作ったIHello.dllを参照しなければInterfaceの継承関係が結べませんので、
  まずは参照設定にArt.IHello.dllを参照するようにします。
  

  これも先ほど同様でクラスライブラリのプロジェクトを作成します。
  名前は「Art.HelloImpl」にしました。

using System;
using System.Collections.Generic;
using System.Text;

namespace Art
{
    public class HelloImpl : IHello
    {
        #region IHello メンバ

        public void ShowMessage(string msg)
        {
            Console.WriteLine(msg);
        }

        #endregion
    }
}      

  簡単ですが、これで実相は終わり。
  ちゃんとビルドしてますよね??

4.さーここまで出来たらあとはDIを使って依存性の注入(DI)をしましょう!!

  まず、テスト用のプロジェクトを作成します。
  今回はコンソールアプリケーションでテストしてみることにしました。
  名前は「Art.DITest」にしました(TestにするかTesterにするか迷いました・・・Testerのほうがよかったかなー)
  

  さてまずDI用のライブラリーを参照設定します。

  下記の二つのDLLをとりあえず参照設定に加えてください。

   ・ s2container.net-1.2.8\s2container.net\build\net2.0\Seasar.dll
   ・ s2container.net-1.2.8\s2container.net\lib\net2.0\log4net.dll

  また、IHelloインターフェイスをコード上に使用するため参照が必要になります。
  ただし、HelloImplは参照設定に追加しないでください。というかできないはずです。



  さらにプロジェクトにアプリケーション構成ファイルを追加しましょう。
  



  次にプロジェクトにDICONファイルを追加しましょう。
  これはアプリケーション構成ファイルをリネームしてApp.diconという名前にすればそれがDICONファイルになります。

  

  そして、デフォルトであるProgram.csにコードを書くことにします。

using System;
using System.Collections.Generic;
using System.Text;
using Seasar.Framework.Container;
using Seasar.Framework.Container.Factory;

namespace Art.DITest
{
    class Program
    {
        static void Main(string[] args)
        {
            SingletonS2ContainerFactory.Init();
            IHello hello = SingletonS2ContainerFactory.Container.GetComponent("Hello") as IHello;
            hello.ShowMessage("こんにちは");
        }
    }
}
    



  また、App.configファイルには下記のように記述しましょう。

<configuration>
        <configSections>
                <section name="seasar" type="Seasar.Framework.Xml.S2SectionHandler, Seasar" />
        </configSections>
        <seasar>
                <configPath>App.dicon</configPath>
                <assemblys>
                        <assembly>Art.IHello</assembly>
                        <assembly>Art.HelloImpl</assembly>
                </assemblys>
        </seasar>
</configuration>     



  App.diconファイルには下記のように記述します。

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container//EN"
"http://www.seasar.org/dtd/components.dtd">
<components>
        <component name="Hello" class="Art.HelloImpl" />
</components>     

  ここでApp.diconのプロパティを変更する必要があります。
  ビルドアクションを「コンテンツ」」に変更
  出力ディレクトリにコピーを「新しい場合はコピーする」に変更します。

  


  さらにもう一点、必要なことがあります。
  Art.IHello.dllとArt..HelloImpl.dllをビルドの出力先にコピーしておく必要があります。

  


  さて、ではビルドしてみましょう!!

  そして実行!!

  

  こんなのでましたか??
  でれば成功です。





---------------------------------------------------------------------

  さて、これだけではDIの真価がさっぱりわかりません。
  ではArt.IHelloの実装をもうひとパターン作成してみます。

  今度はMessageBoxで出力するようにします。
  もちろんSystem.Windows.Forms.dllを参照設定に加えてください。

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;

namespace Art
{
    class Hello2Impl : IHello
    {
        #region IHello メンバ

        public void ShowMessage(string msg)
        {
            MessageBox.Show(msg);
        }

        #endregion
    }
}    



  それでは先ほどのArt.Testの実行ファイルがあるフォルダにArt.Hello2Implを追加します。

  そして、Art.DITest.exe.configというファイルがあると思いますが、それに変更を加えます。メモ帳か何かでよいでしょう。
  みたまんまですが、これはApp.configファイルがVisualStudioによって勝手にリネームされたものです。

<configuration>
        <configSections>
                <section name="seasar" type="Seasar.Framework.Xml.S2SectionHandler, Seasar" />
        </configSections>
        <seasar>
                <configPath>App.dicon</configPath>
                <assemblys>
                        <assembly>Art.IHello</assembly>
                        <assembly>Art.HelloImpl</assembly>
                        <assembly>Art.Hello2Impl</assembly>
                </assemblys>
        </seasar>
</configuration>

 
  さらにApp.diconファイルにも変更を加えます。

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container//EN"
"http://www.seasar.org/dtd/components.dtd">
<components>
        <component name="Hello" class="Art.Hello2Impl" />
</components>


  では、そのデイレクトリ内にあるArt.DITest.exeを実行してみましょう!!

  

  メッセージボックスが出力されれば成功です!

  どうです?
  設定ファイルを変更するだけでソースコードを変更することなく
  コンパイルも不要で実装が変更することができました。



  これがDIコンテナってやつなんです。




  ちなみにDIを使わずに書くと

  Art.IHelloとArt.HelloImplの参照設定する必要があります。
  下記のようなコードになります。
  
using System;
using System.Collections.Generic;
using System.Text;

namespace Art.DITestnoDI
{
    class Program
    {
        static void Main(string[] args)
        {
            IHello hello = new HelloImpl();
            hello.ShowMessage("こんにちは");
        }
    }
}     

  インターフェイスもその実装もTestプログラムが依存関係にあるために実装を変更した場合、
  再コンパイルが必要となります。
  あーもしかすると同名のDLLで同盟の実装メソッドであればDLLを差し替えるだけで動くかもしれません・・・。