<?xml version="1.0" encoding="UTF-8" ?> <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>EntLib</title><link>http://blogs.wankuma.com/kazuki/category/1894.aspx</link><description>EntLib</description><managingEditor>k.ota.0130あっとgmail.com(かずき)</managingEditor><dc:language>ja-JP</dc:language><generator>.Text Version 0.95.2004.102</generator><item><dc:creator>kazuki@wankuma.com (かずき)</dc:creator><title>[C#][EntLib]Data Access Application Blockお試し</title><link>http://blogs.wankuma.com/kazuki/archive/2008/11/09/160823.aspx</link><pubDate>Sun, 09 Nov 2008 14:30:00 GMT</pubDate><guid>http://blogs.wankuma.com/kazuki/archive/2008/11/09/160823.aspx</guid><wfw:comment>http://blogs.wankuma.com/kazuki/comments/160823.aspx</wfw:comment><comments>http://blogs.wankuma.com/kazuki/archive/2008/11/09/160823.aspx#Feedback</comments><slash:comments>156</slash:comments><wfw:commentRss>http://blogs.wankuma.com/kazuki/comments/commentRss/160823.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/kazuki/services/trackbacks/160823.aspx</trackback:ping><description>&lt;p&gt;次は、Data Access Application BLockを触ってみようと思う。&lt;br&gt;ざっとドキュメントを見た感じの印象だと、Data Access Application Block(DAAB)を使うと、DBに依存しないアプリケーションが作りやすくなるよっ！&lt;br&gt;ADO.NETの素のAPIみたいに煩雑なプログラミングしなくてもよくなるよっ！&lt;/p&gt; &lt;p&gt;ってのがいいみたい。&lt;br&gt;雑にいっちゃうとADO.NETを、いい感じにラップしてくれているもののようです。&lt;/p&gt; &lt;p&gt;ということで、早速お試し。&lt;/p&gt; &lt;h1&gt;プロジェクトの作成&lt;/h1&gt; &lt;p&gt;DAABSampleという名前でコンソールアプリケーションを作成する。&lt;br&gt;そこに、必要な参照を追加する。追加するものは以下の５つ。&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Enterprise Library Data Access Application Block&lt;/li&gt; &lt;li&gt;Enterprise Library Shared Library&lt;/li&gt; &lt;li&gt;Microsoft.Practices.ObjectBuilder2&lt;/li&gt; &lt;li&gt;Microsoft.Practices.Unity&lt;/li&gt; &lt;li&gt;System.Configuration&lt;/li&gt;&lt;/ol&gt; &lt;h1&gt;データベースの作成&lt;/h1&gt; &lt;p&gt;データベースにアクセスするプログラムを作るので、DBが無いと始まらない。&lt;br&gt;ということで、Visual StudioのサーバーエクスプローラからSQL ServerのDBを新規作成した。&lt;br&gt;&lt;a href="http://kazuki.wankuma.com/images/2008/04/CEntLibDataAccessApplicationBlock_A911/image.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="123" alt="image" src="http://kazuki.wankuma.com/images/2008/04/CEntLibDataAccessApplicationBlock_A911/image_thumb.png" width="244" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;DB名は、DAABSampleDBにした。&lt;br&gt;&lt;a href="http://kazuki.wankuma.com/images/2008/04/CEntLibDataAccessApplicationBlock_A911/image_3.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="244" alt="image" src="http://kazuki.wankuma.com/images/2008/04/CEntLibDataAccessApplicationBlock_A911/image_thumb_3.png" width="199" border="0"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;テーブルは、ありきたりな従業員(Employees)テーブルと部署（Departments）テーブルの２つを作ってEmployeesのDepartmentID列とDepartmentsのID列を外部キーで結んだ。&lt;br&gt;両テーブルの主キー列は、IDENTITYの設定をして自動で番号がふられるようにしておいた。&lt;br&gt;&lt;a href="http://kazuki.wankuma.com/images/2008/04/CEntLibDataAccessApplicationBlock_A911/image_4.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="166" alt="image" src="http://kazuki.wankuma.com/images/2008/04/CEntLibDataAccessApplicationBlock_A911/image_thumb_4.png" width="205" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;このテーブルに対して色々やっていこうと思う。 &lt;/p&gt; &lt;h1&gt;構成ファイルの編集&lt;/h1&gt; &lt;p&gt;DBも準備できたので、続いてEnterprise Libraryではお馴染み構成ファイルを組み立てていこうと思う。&lt;br&gt;App.configをプロジェクトに追加して、右クリックメニューからEdit Enterprise Library Configurationを選択してApp.configを開く。&lt;br&gt;&lt;a href="http://kazuki.wankuma.com/images/2008/04/CEntLibDataAccessApplicationBlock_A911/image_5.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="133" alt="image" src="http://kazuki.wankuma.com/images/2008/04/CEntLibDataAccessApplicationBlock_A911/image_thumb_5.png" width="244" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;Data Access Application Blockが何故か自動的に作られているので、そこにあるLocal Sql Serverを選択してプロパティを編集していく。&lt;br&gt;&lt;a href="http://kazuki.wankuma.com/images/2008/04/CEntLibDataAccessApplicationBlock_A911/image_6.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="149" alt="image" src="http://kazuki.wankuma.com/images/2008/04/CEntLibDataAccessApplicationBlock_A911/image_thumb_6.png" width="275" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;Local Sql Serverのノードには、Name, ConnectionString, Provider Nameの３つのプロパティがある。&lt;br&gt;ここを適時設定していく。今回はNameをDAABSample、ConnectionStringを先ほど作ったDBのものに変更する。&lt;br&gt;ProviderNameは、SQL ServerなのでそのままでOK。&lt;/p&gt; &lt;p&gt;次に、Data Access Application Blockのノードを選択してDefaultDatabaseをDAABSampleに設定する。&lt;br&gt;こうすることで、プログラム側で名前を指定しない場合に、自動的にDAABSampleが使われるようになる。&lt;br&gt;&lt;a href="http://kazuki.wankuma.com/images/2008/04/CEntLibDataAccessApplicationBlock_A911/image_7.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="107" alt="image" src="http://kazuki.wankuma.com/images/2008/04/CEntLibDataAccessApplicationBlock_A911/image_thumb_7.png" width="244" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;設定は基本的に以上で終了。&lt;br&gt;やったことをまとめると。&lt;/p&gt; &lt;ol&gt; &lt;li&gt;App.config追加&lt;/li&gt; &lt;li&gt;Data Access Application BLock/Connection Stringsの下にDBへの接続文字列と名前の設定&lt;/li&gt; &lt;li&gt;Data Access Application BlockのDefaultDatabaseの設定&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;やることが少なくてよろしい。&lt;/p&gt; &lt;h1&gt;ついにプログラミング&lt;/h1&gt; &lt;p&gt;下準備が整ったのでプログラミングに入ろうと思う。&lt;br&gt;Enterprise Library 4.0から、UnityContainerを中心に物事が進むようになっているので、まずUnityContainerのインスタンスを生成する。&lt;/p&gt; &lt;p&gt;そこに、EnterpriseLibraryCoreExtensionとDataAccessBlockExtensionを追加する。この３つを追加することで、さっき作った構成ファイルをもとにコンテナ内にインスタンスの登録などが行われる。&lt;/p&gt; &lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:4bac131e-c473-400d-aa0f-5c6fa88b483e" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;IUnityContainer container = new UnityContainer();
container.AddNewExtension&amp;lt;EnterpriseLibraryCoreExtension&amp;gt;();
container.AddNewExtension&amp;lt;DataAccessBlockExtension&amp;gt;();
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;次に、Databaseオブジェクトを取得する。&lt;br&gt;いつもどおりUnityを使うようにResolveメソッドを使うことでインスタンスの取得が出来る。&lt;/p&gt;
&lt;p&gt;
&lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:aed31ddd-a3be-4685-a950-d857431bef34" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;// Databaseのインスタンスを取得
var database = container.Resolve&amp;lt;Database&amp;gt;();
// 接続文字列等を出力して正しく取得できているか確認
Console.WriteLine(database.ConnectionString);
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;正しく設定が出来ていれば、先ほど構成ファイルに記述した接続文字列がコンソールに出力される。&lt;br&gt;ここにDBアクセスする処理を足していこうと思う。&lt;/p&gt;
&lt;h2&gt;データの登録処理&lt;/h2&gt;
&lt;p&gt;まだDBのほうに何もデータが入っていないのでINSERT系の処理を書いていく。&lt;br&gt;とりあえず、データの登録は一度やっちゃえばいいので、privateメソッドに切り出して書いてみた。&lt;/p&gt;
&lt;p&gt;
&lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:de0e34bb-9108-4f4f-80c9-f34596a681dd" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;// DBにデータを登録する
private static void DoInsert(Database database)
{
    // 部署データを３つ準備
    var depts = new[]
        {
            new { ID = 1, Name = "人事部" },
            new { ID = 2, Name = "総務部" },
            new { ID = 3, Name = "営業部" }
        };

    // 部署データ登録用のDbCommand作成
    DbCommand insertDept = database.GetSqlStringCommand(
        "insert into Departments(ID, Name) values(@ID, @Name)");
    // パラメータの登録
    database.AddInParameter(insertDept, "ID", DbType.Int64);
    database.AddInParameter(insertDept, "Name", DbType.String);

    // データの登録
    foreach (var dept in depts)
    {
        database.SetParameterValue(insertDept, "ID", dept.ID);
        database.SetParameterValue(insertDept, "Name", dept.Name);
        database.ExecuteNonQuery(insertDept);
    }

    // 登録用の従業員データを４つ準備
    var emps = new[]
        {
            new { ID = 1, Name = "田中　太郎", DepartmentID = 1 },
            new { ID = 2, Name = "鈴木　次郎", DepartmentID = 2 },
            new { ID = 3, Name = "丸井　三郎", DepartmentID = 3 },
            new { ID = 4, Name = "木村　四郎", DepartmentID = 3 }
        };

    // 従業員データ登録用のDbCommand作成
    DbCommand insertEmp = database.GetSqlStringCommand(
        "insert into Employees(ID, Name, DepartmentID) values(@ID, @Name, @DepartmentID)");
    // パラメータの登録
    database.AddInParameter(insertEmp, "ID", DbType.Int64);
    database.AddInParameter(insertEmp, "Name", DbType.String);
    database.AddInParameter(insertEmp, "DepartmentID", DbType.Int64);

    foreach (var emp in emps)
    {
        database.SetParameterValue(insertEmp, "ID", emp.ID);
        database.SetParameterValue(insertEmp, "Name", emp.Name);
        database.SetParameterValue(insertEmp, "DepartmentID", emp.DepartmentID);
        database.ExecuteNonQuery(insertEmp);
    }
}
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;長いけど、これを実行すると下のようなデータがDBに入る。&lt;br&gt;&lt;br&gt;&lt;strong&gt;&lt;u&gt;Departmentsテーブル&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;table cellspacing="0" cellpadding="2" width="197" border="0"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td valign="top" width="66"&gt;&lt;strong&gt;ID&lt;/strong&gt;&lt;/td&gt;
&lt;td valign="top" width="129"&gt;&lt;strong&gt;Name&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top" width="68"&gt;1&lt;/td&gt;
&lt;td valign="top" width="129"&gt;人事部&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top" width="70"&gt;2&lt;/td&gt;
&lt;td valign="top" width="129"&gt;総務部&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top" width="71"&gt;3&lt;/td&gt;
&lt;td valign="top" width="129"&gt;営業部&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;&lt;u&gt;Employeesテーブル&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;table cellspacing="0" cellpadding="2" width="400" border="0"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td valign="top" width="133"&gt;&lt;strong&gt;ID&lt;/strong&gt;&lt;/td&gt;
&lt;td valign="top" width="133"&gt;&lt;strong&gt;Name&lt;/strong&gt;&lt;/td&gt;
&lt;td valign="top" width="133"&gt;&lt;strong&gt;DepartmentID&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top" width="133"&gt;1&lt;/td&gt;
&lt;td valign="top" width="133"&gt;田中　太郎&lt;/td&gt;
&lt;td valign="top" width="133"&gt;1&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top" width="133"&gt;2&lt;/td&gt;
&lt;td valign="top" width="133"&gt;鈴木　次郎&lt;/td&gt;
&lt;td valign="top" width="133"&gt;2&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top" width="133"&gt;3&lt;/td&gt;
&lt;td valign="top" width="133"&gt;丸井　三郎&lt;/td&gt;
&lt;td valign="top" width="133"&gt;3&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top" width="133"&gt;4&lt;/td&gt;
&lt;td valign="top" width="133"&gt;木村　四郎&lt;/td&gt;
&lt;td valign="top" width="133"&gt;3&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;更新系のSQLの発行までの流れは以下の通り。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;database.GetSqlStringCommandメソッドでDbCommandを作成&lt;/li&gt;
&lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:50a1c122-a235-4358-926f-b26fba3f731f" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;DbCommand insertDept = database.GetSqlStringCommand(
     "insert into Departments(ID, Name) values(@ID, @Name)");
&lt;/pre&gt;&lt;/div&gt;
&lt;li&gt;database.AddInParameterでパラメータの定義&lt;/li&gt;
&lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:657836ad-77ab-45fc-984c-1c65b7b9f595" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;// パラメータの登録
database.AddInParameter(insertDept, "ID", DbType.Int64);
database.AddInParameter(insertDept, "Name", DbType.String);
&lt;/pre&gt;&lt;/div&gt;
&lt;li&gt;database.SetParameterValueでパラメータの値の設定&lt;/li&gt;
&lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:addb3e41-3b7a-42a6-8ea5-b68584439cdf" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;database.SetParameterValue(insertDept, "ID", dept.ID);
database.SetParameterValue(insertDept, "Name", dept.Name);
&lt;/pre&gt;&lt;/div&gt;
&lt;li&gt;database.ExecuteNonQueryでSQL文の実行&lt;/li&gt;
&lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:c297aaef-9aed-4aee-80e9-ce377d29006a" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;database.ExecuteNonQuery(insertDept);&lt;/pre&gt;&lt;/div&gt;&lt;/ol&gt;
&lt;p&gt;この一連の処理をTransactionScopeで括ってやると、トランザクションもばっちりになる。&lt;br&gt;しかも、TransactionScopeを使ってると、コネクションを自動でキャッシュしてくれるらしいので、ローカルなトランザクションで済むという素敵なつくりになっているみたいです。&lt;/p&gt;
&lt;h2&gt;データの検索処理&lt;/h2&gt;
&lt;p&gt;データの準備が出来たので、検索系の処理のときの例も作ってみる。&lt;/p&gt;
&lt;p&gt;
&lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:1bd3ad5c-d72e-4b0f-b540-6ace614b6e49" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;// DbCommandを作成してパラメータの設定を行う
DbCommand cmd = database.GetSqlStringCommand(
    "select d.ID, d.Name from Departments d where ID = @ID");
database.AddInParameter(cmd, "ID", DbType.Int64);
database.SetParameterValue(cmd, "ID", 1);

// DataSetを作成して、そこにSQLの結果を読み込む
DataSet ds = new DataSet();
database.LoadDataSet(cmd, ds, "Departments");

// 試しにデータを出力してみる
DataTable deptTable = ds.Tables["Departments"];
Console.WriteLine(deptTable.TableName);
DataRow deptRow = deptTable.Rows[0];
Console.WriteLine("Dept: ID = {0}, Name = {1}", deptRow["ID"], deptRow["Name"]); // -&amp;gt; Dept: ID = 1, Name = 人事部
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;これも、基本的にDbCommandを作ってパラメータの定義と値を設定する。&lt;br&gt;そして、Databaseクラスに定義されている、各種読み込みメソッドを使ってデータを読み込む。&lt;br&gt;今回は、LoadDataSetを使ってDataSetに直接SQLの実行結果を取り込んでいる。&lt;/p&gt;
&lt;p&gt;IDataReaderを使う場合はExecuteReaderメソッドを使う。&lt;/p&gt;
&lt;p&gt;
&lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:4e626d1f-e447-47a7-b61d-e50b7655498d" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;using(IDataReader r = database.ExecuteReader(cmd))
{
    while (r.Read())
    {
        long id = r.GetInt64(0);
        string name = r.GetString(1);
        Console.WriteLine("Dept: ID = {0}, Name = {1}", id, name);
    }
}
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;ExecuteReaderの結果のIDataReaderは、きちんとCloseしないといけない。とりあえず、usingで括っておけばOK。&lt;/p&gt;
&lt;h1&gt;試してみた感想&lt;/h1&gt;
&lt;p&gt;試してみていいな～と思った部分を列挙してみる。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;コネクションを意識しなくてもいい&lt;/li&gt;
&lt;li&gt;ADO.NETで直接やるよりコードが少なくなる&lt;/li&gt;
&lt;li&gt;TransactionScopeとの相性もよさそうらしい&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;次に、どうなんだろ？と思った点は&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;型付きデータセットとの相性は、そこまでよくないかも？&lt;br&gt;型付きデータセットを普通に作るとTableAdapterまで作られちゃうからそっち使っちゃいそう。&lt;/li&gt;
&lt;li&gt;DataSetではない、普通のClassへデータを詰め替えるのがメンドクサイかも？&lt;br&gt;IDataReaderを使って地道にぐるぐる回すしかなさそう。（ユーテリティクラス作ればいいか）&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;全体的には、シンプルになっていいな～と思った。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/kazuki/aggbug/160823.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>kazuki@wankuma.com (かずき)</dc:creator><title>[C#][EntLib]UnityContainerの拡張について</title><link>http://blogs.wankuma.com/kazuki/archive/2008/11/05/160514.aspx</link><pubDate>Wed, 05 Nov 2008 13:08:00 GMT</pubDate><guid>http://blogs.wankuma.com/kazuki/archive/2008/11/05/160514.aspx</guid><wfw:comment>http://blogs.wankuma.com/kazuki/comments/160514.aspx</wfw:comment><comments>http://blogs.wankuma.com/kazuki/archive/2008/11/05/160514.aspx#Feedback</comments><slash:comments>104</slash:comments><wfw:commentRss>http://blogs.wankuma.com/kazuki/comments/commentRss/160514.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/kazuki/services/trackbacks/160514.aspx</trackback:ping><description>&lt;p&gt;さて、UnityContainerの拡張のお話。&lt;br&gt;UnityContainerExtensionを実装する形で作成するという例を&lt;a href="http://blogs.wankuma.com/kazuki/archive/2008/07/31/151322.aspx"&gt;ちょっと前&lt;/a&gt;に書いた。&lt;/p&gt; &lt;p&gt;今日は、もうちょっと掘り下げてみようと思う。&lt;br&gt;前回の例では、UnityContainerExtensionのInitializeメソッドでフレームワークで使用するクラス群を登録しちゃえば便利そうだね～と言った。&lt;br&gt;今回は、それに加えてUnityContainerがクラスのインスタンスを生成する過程に割り込む方法を書いてみようと思う。&lt;/p&gt; &lt;p&gt;UnityContainerExtensionにはContextというプロパティがある。Contextの型はExtensionContextという型で、ここに色々なメソッドやプロパティが定義されている。&lt;br&gt;その中の１つにStrategiesというプロパティがある。&lt;/p&gt; &lt;p&gt;ここに、Microsoft.Practices.ObjectBuilder2.IBuilderStrategyを実装したクラスをAddメソッドを使って追加することで色々出来るようになる。&lt;/p&gt; &lt;p&gt;IBuilderStrategyインターフェースのメソッドは、以下の４つになる。&lt;/p&gt; &lt;ol&gt; &lt;li&gt;PostBuildUp&lt;/li&gt; &lt;li&gt;PostTearDown&lt;/li&gt; &lt;li&gt;PreBuildUp&lt;/li&gt; &lt;li&gt;PreTearDown&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;この中で、オブジェクトの生成に関わるメソッドは、PreBuildUpとPostBuildUpの２つになる。&lt;br&gt;～TearDownのほうは、IUnityContainerのTearDownメソッドを呼んでインスタンスを破棄するときに使われるので、今回はとりあえず無視する。&lt;/p&gt; &lt;p&gt;とりあえず、日本語で詳しく書かれた情報が見当たらなかったので適当に実装して動きを見てみるために適当な実装をでっちあげた。&lt;/p&gt; &lt;p&gt; &lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:5df9ec9a-e6f9-4306-b1d9-d006c232eb6e" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;public class MyStragety : IBuilderStrategy
{
    private string stage;
    public MyStragety(string stage)
    {
        this.stage = stage;
    }

    #region IBuilderStrategy メンバ

    public void PostBuildUp(IBuilderContext context)
    {
        Print("PostBuildUp", context);
    }

    public void PostTearDown(IBuilderContext context)
    {
        // no op
    }

    public void PreBuildUp(IBuilderContext context)
    {
        Print("PreBuildUp", context);
    }

    public void PreTearDown(IBuilderContext context)
    {
        // no op
    }

    private void Print(string method, IBuilderContext context)
    {
        Console.WriteLine(stage + ", " + method);
    }

    #endregion
}&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;これを登録するExtensionも作成する。&lt;/p&gt;
&lt;p&gt;
&lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:bc3c2736-d1d1-45f1-b23d-fa71d31ab80b" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;public class MyExtension : UnityContainerExtension
{
    protected override void Initialize()
    {
        Context.Strategies.Add(new MyStragety("Creation"), UnityBuildStage.Creation);
        Context.Strategies.Add(new MyStragety("Initialization"), UnityBuildStage.Initialization);
        Context.Strategies.Add(new MyStragety("Lifetime"), UnityBuildStage.Lifetime);
        Context.Strategies.Add(new MyStragety("PostInitialization"), UnityBuildStage.PostInitialization);
        Context.Strategies.Add(new MyStragety("PreCreation"), UnityBuildStage.PreCreation);
        Context.Strategies.Add(new MyStragety("Setup"), UnityBuildStage.Setup);
        Context.Strategies.Add(new MyStragety("TypeMapping"), UnityBuildStage.TypeMapping);
    }
}
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;さっきは、説明しなかったけどStrategiesのAddメソッドには、Stageと呼ばれるものも一緒に登録する。&lt;br&gt;これがどういう意味を持つのかわからないので、一応全部登録して動きを見てみることにした。&lt;/p&gt;
&lt;p&gt;そして、このExtensionを追加して動きを確認するサンプルを作って動きを見てみた。&lt;/p&gt;
&lt;p&gt;
&lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:1f39aac8-4259-4b3a-a460-add54f4f2aac" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;public interface IFoo
{
    void Foo();
}
public class FooImpl : IFoo
{
    public void Foo() { Console.WriteLine("Foo"); }
}

class Program
{
    static void Main(string[] args)
    {
        IUnityContainer container = new UnityContainer();
        container.AddNewExtension&amp;lt;MyExtension&amp;gt;();
        container.RegisterType&amp;lt;IFoo, FooImpl&amp;gt;();

        Console.WriteLine("Resolveするよ!!");
        var foo = container.Resolve&amp;lt;IFoo&amp;gt;();
        foo.Foo();

    }
}
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;これを実行すると、ちょっと長いけど下のような実行結果になった。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Resolveするよ!!&lt;br&gt;Setup, PreBuildUp&lt;br&gt;TypeMapping, PreBuildUp&lt;br&gt;Lifetime, PreBuildUp&lt;br&gt;PreCreation, PreBuildUp&lt;br&gt;Creation, PreBuildUp&lt;br&gt;Initialization, PreBuildUp&lt;br&gt;PostInitialization, PreBuildUp&lt;br&gt;PostInitialization, PostBuildUp&lt;br&gt;Initialization, PostBuildUp&lt;br&gt;Creation, PostBuildUp&lt;br&gt;PreCreation, PostBuildUp&lt;br&gt;Lifetime, PostBuildUp&lt;br&gt;TypeMapping, PostBuildUp&lt;br&gt;Setup, PostBuildUp&lt;br&gt;Foo&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Setup, TypeMapping, Lifetime, PreCreation, Creation, Initialization, PostInitializationの順番でPreBuildUpが呼ばれて、今度は逆順にPostBuildUpが呼ばれてるのがわかると思う。&lt;br&gt;きっと各フェーズで何か処理がされているのだろうけど、ちょっと調べるのは今度にして簡単なサンプルを作ってみた。&lt;/p&gt;
&lt;p&gt;サンプルは、IFooインターフェースを実装したクラスを作るときにこっそりインスタンスに細工をするというものにしてみた。&lt;/p&gt;
&lt;p&gt;
&lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:a44674e4-261c-4033-ba7d-7984894613fe" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;public interface IFoo
{
    void Foo();
}
public class FooImpl : IFoo
{
    public void Foo() { Console.WriteLine("Foo"); }
}

public class FooDecoratorExtension : UnityContainerExtension
{
    protected override void Initialize()
    {
        // 無条件にIFooをデコレートするStrategyを仕込む
        Context.Strategies.Add(
            new FooDecoratorStrategy(),
            UnityBuildStage.Creation);
    }
}

/// &amp;lt;summary&amp;gt;
/// IFooを作成しようとした場合に、無条件にFooDecoratorでデコレートする
/// &amp;lt;/summary&amp;gt;
public class FooDecoratorStrategy : IBuilderStrategy
{
    #region IBuilderStrategy メンバ

    public void PostBuildUp(IBuilderContext context)
    {
        // IFooならFooDecoratorでくるむ
        if (context.Existing is IFoo)
        {
            context.Existing = new FooDecorator((IFoo)context.Existing);
        }
    }

    public void PostTearDown(IBuilderContext context)
    {
    }

    public void PreBuildUp(IBuilderContext context)
    {
    }

    public void PreTearDown(IBuilderContext context)
    {
    }

    #endregion
}


/// &amp;lt;summary&amp;gt;
/// IFooを飾り付けるよ
/// &amp;lt;/summary&amp;gt;
public class FooDecorator : IFoo
{
    private IFoo org;

    public FooDecorator(IFoo org)
    {
        this.org = org;
    }

    public void Foo()
    {
        Console.WriteLine("デコレート！！");
        org.Foo();
        Console.WriteLine("デコレート！！");
    }
}


class Program
{
    static void Main(string[] args)
    {
        IUnityContainer container = new UnityContainer();
        container.AddNewExtension&amp;lt;FooDecoratorExtension&amp;gt;();
        container.RegisterType&amp;lt;IFoo, FooImpl&amp;gt;();

        Console.WriteLine("Resolveするよ!!");
        var foo = container.Resolve&amp;lt;IFoo&amp;gt;();
        foo.Foo();

    }
}
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;これを実行すると、以下のような結果になる。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Resolveするよ!!&lt;br&gt;デコレート！！&lt;br&gt;Foo&lt;br&gt;デコレート！！&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;これは、フレームワークとかで特定の型の場合に何か細工入れ込むとかステキな処理が出来そうだ。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/kazuki/aggbug/160514.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>kazuki@wankuma.com (かずき)</dc:creator><title>[C#][EntLib]Policy Injection Application Block その３</title><link>http://blogs.wankuma.com/kazuki/archive/2008/11/04/160425.aspx</link><pubDate>Tue, 04 Nov 2008 01:10:00 GMT</pubDate><guid>http://blogs.wankuma.com/kazuki/archive/2008/11/04/160425.aspx</guid><wfw:comment>http://blogs.wankuma.com/kazuki/comments/160425.aspx</wfw:comment><comments>http://blogs.wankuma.com/kazuki/archive/2008/11/04/160425.aspx#Feedback</comments><slash:comments>31</slash:comments><wfw:commentRss>http://blogs.wankuma.com/kazuki/comments/commentRss/160425.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/kazuki/services/trackbacks/160425.aspx</trackback:ping><description>&lt;p&gt;Policy Injection Application Blockを2回試してみた感想は、Unityと相性悪そう。&lt;br&gt;ということでぐぐってみると、下のスレッドを見つけた。&lt;br&gt;&lt;a title="http://www.codeplex.com/unity/Thread/View.aspx?ThreadId=38040" href="http://www.codeplex.com/unity/Thread/View.aspx?ThreadId=38040"&gt;http://www.codeplex.com/unity/Thread/View.aspx?ThreadId=38040&lt;/a&gt;&lt;/p&gt; &lt;p&gt;どうやらPolicy Injection Application Blockの設定をUnityのInterceptionに食わせることが出来るみたい。&lt;br&gt;早速やってみた。前までのプロジェクトのMainメソッドを下のように書き換えた。&lt;/p&gt; &lt;p&gt; &lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:1ffa6ecd-090a-42af-928f-493d3a7f71e6" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;    class Program
    {
        static void Main(string[] args)
        {
            // Targetクラスのインスタンスを作成して
            // var target = PolicyInjection.Create&amp;lt;Target&amp;gt;();
            // 処理を呼び出す
            // target.Greet();

            IUnityContainer container = new UnityContainer();
            container.AddNewExtension&amp;lt;Interception&amp;gt;();
            container.Configure&amp;lt;Interception&amp;gt;().SetInterceptorFor&amp;lt;Target&amp;gt;(new TransparentProxyInterceptor());

            var configSource = ConfigurationSourceFactory.Create();
            var settings = (PolicyInjectionSettings)configSource.GetSection(PolicyInjectionSettings.SectionName);
            settings.ConfigureContainer(container, configSource);

            var target = container.Resolve&amp;lt;Target&amp;gt;();
            target.Greet();
        }
    }
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;実行結果は、今までのと同じなので省略。&lt;br&gt;ちゃんと動いているけど、SetInterceptorForを型ごとに設定しないといけないのはUnityのInterceptionなので仕方ないのだろうか…。&lt;br&gt;MatchingRuleにマッチする奴は、自動的にTransparentProxyInterceptorを適用するとか出来ないのかな？&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/kazuki/aggbug/160425.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>kazuki@wankuma.com (かずき)</dc:creator><title>[C#][EntLib]Policy Injection Application Blockお試し その２</title><link>http://blogs.wankuma.com/kazuki/archive/2008/11/04/160421.aspx</link><pubDate>Tue, 04 Nov 2008 00:48:00 GMT</pubDate><guid>http://blogs.wankuma.com/kazuki/archive/2008/11/04/160421.aspx</guid><wfw:comment>http://blogs.wankuma.com/kazuki/comments/160421.aspx</wfw:comment><comments>http://blogs.wankuma.com/kazuki/archive/2008/11/04/160421.aspx#Feedback</comments><slash:comments>517</slash:comments><wfw:commentRss>http://blogs.wankuma.com/kazuki/comments/commentRss/160421.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/kazuki/services/trackbacks/160421.aspx</trackback:ping><description>&lt;p&gt;1つ前の記事で、メソッド呼び出しの前後にログを挟み込むPIABの使い方を試してみた。&lt;br&gt;今回は、あり合わせのHandlerじゃなくて、独自のHandlerを作ってみようと思う。&lt;/p&gt; &lt;p&gt;前回のプロジェクトにクラスライブラリのプロジェクトを１つ追加する。&lt;br&gt;名前はMyHandlersにした。&lt;/p&gt; &lt;p&gt;MyHandlersプロジェクトに以下の参照を追加する。&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Enterprise Library Policy Injection Application Block&lt;/li&gt; &lt;li&gt;Enterprise Library Shared Library&lt;/li&gt; &lt;li&gt;Microsoft.Practices.Unity&lt;/li&gt; &lt;li&gt;Microsoft.Practices.Unity.InterceptionExtension&lt;/li&gt; &lt;li&gt;Microsoft.Practices.ObjectBuilder2&lt;/li&gt; &lt;li&gt;System.Configuration&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Unity関連の3つの参照は、PIABSampleAppのほうにも追加しておく。&lt;/p&gt; &lt;p&gt;PIABのカスタムハンドラをここに作成していく。カスタムハンドラになるためには、最低限以下の条件を満たしてないといけないみたい。&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Microsoft.Practices.Unity.InterceptionExtension.ICallHandlerを実装する&lt;/li&gt; &lt;li&gt;[ConfigurationElementType(typeof(CustomCallHandlerData))]属性がついている&lt;/li&gt; &lt;li&gt;NameValueCollectionを受け取るコンストラクタがある&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;ということで実装開始。とりあえず、メソッド呼び出しの前後に標準出力にメッセージをだすようにしてみた。&lt;/p&gt; &lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:2c44088c-df50-483e-be01-554389457c63" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;using System;
using System.Collections.Specialized;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.PolicyInjection.Configuration;
using Microsoft.Practices.Unity.InterceptionExtension;

namespace MyHandlers
{
    [ConfigurationElementType(typeof(CustomCallHandlerData))]
    public class MyHandler : ICallHandler
    {
        // このコンストラクタ必須！
        public MyHandler(NameValueCollection attributes) { }

        public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
        {
            // 本来の処理の呼び出しの前後に、クラス名とメソッド名を出力する
            var name = input.Target.GetType() + "." + input.MethodBase.Name;
            Console.WriteLine("Before: " + name);
            try
            {
                return getNext().Invoke(input, getNext);
            }
            finally
            {
                Console.WriteLine("After: " + name);
            }
        }
        public int Order { get; set; }
    }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;PIABSampleAppの参照に、今作成したMyHandlersを追加する。そして、App.configを以下のように構成する。&lt;/p&gt;
&lt;p&gt;前のサンプルで作っていたLogging Handlerを削除して、かわりにCustom Handlerを追加する。&lt;br&gt;&lt;a href="http://kazuki.wankuma.com/images/2008/CEntLibPolicyInjectionApplicationBlock_B42/image.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="178" alt="image" src="http://kazuki.wankuma.com/images/2008/CEntLibPolicyInjectionApplicationBlock_B42/image_thumb.png" width="559" border="0"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Custom HandlerのTypeにMyHandlers.MyHandlerを設定する。&lt;br&gt;Typeプロパティの横のボタンを押して、Handlerを選択するためのダイアログを表示する。そして、MyHandlers.dllを開く。そうするとMyHandlerが選択できるので選択してOKをクリックする。&lt;br&gt;&lt;a href="http://kazuki.wankuma.com/images/2008/CEntLibPolicyInjectionApplicationBlock_B42/image_3.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="166" alt="image" src="http://kazuki.wankuma.com/images/2008/CEntLibPolicyInjectionApplicationBlock_B42/image_thumb_3.png" width="244" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;TypeにMyHandlerが設定される。&lt;br&gt;&lt;a href="http://kazuki.wankuma.com/images/2008/CEntLibPolicyInjectionApplicationBlock_B42/image_4.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="54" alt="image" src="http://kazuki.wankuma.com/images/2008/CEntLibPolicyInjectionApplicationBlock_B42/image_thumb_4.png" width="758" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt; これで、実行すると下のような実行結果になる。自作のHandlerが効いてるのがわかると思う。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;u&gt;実行結果&lt;/u&gt;&lt;/strong&gt;&lt;br&gt;Before: PIABSampleApp.Target.Greet&lt;br&gt;Target.Greet Called.&lt;br&gt;After: PIABSampleApp.Target.Greet&lt;/p&gt;&lt;/blockquote&gt;&lt;img src ="http://blogs.wankuma.com/kazuki/aggbug/160421.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>kazuki@wankuma.com (かずき)</dc:creator><title>[C#][EntLib]Policy Injection Application Blockお試し</title><link>http://blogs.wankuma.com/kazuki/archive/2008/11/04/160417.aspx</link><pubDate>Tue, 04 Nov 2008 00:07:00 GMT</pubDate><guid>http://blogs.wankuma.com/kazuki/archive/2008/11/04/160417.aspx</guid><wfw:comment>http://blogs.wankuma.com/kazuki/comments/160417.aspx</wfw:comment><comments>http://blogs.wankuma.com/kazuki/archive/2008/11/04/160417.aspx#Feedback</comments><slash:comments>218</slash:comments><wfw:commentRss>http://blogs.wankuma.com/kazuki/comments/commentRss/160417.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/kazuki/services/trackbacks/160417.aspx</trackback:ping><description>&lt;p&gt;Enterprice Library 4.1も出たということで、触ってみてる。&lt;br&gt;まだ、LoggingとUnityくらいしか触れてない。&lt;/p&gt; &lt;p&gt;次は、UnityのInterceptionとかぶってるような気がするPolicy Injection Application Blockにチャレンジしてみる。&lt;br&gt;こいつは、説明を見る感じだとAOPみたいなことを実現するものらしい。裏側ではProxyクラスを作って、処理の呼び出しの際に間に処理を挟みこむといった感じになってるようだ。&lt;/p&gt; &lt;p&gt;とりあえず、入門用としてメソッドの呼び出しの前後にログ出力を挟み込むようなサンプルを作ってみようとおもう　。&lt;/p&gt; &lt;h1&gt;プロジェクト作成&lt;/h1&gt; &lt;p&gt;PIABSampleAppという名前でコンソールアプリケーションを作成する。そこに、以下の４つの参照を追加する。&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Enterprise Library Shared Library&lt;/li&gt; &lt;li&gt;Enterprise Library Policy Injection Application Block&lt;/li&gt; &lt;li&gt;Enterprise Library Logging Application Block&lt;/li&gt; &lt;li&gt;Enterprise Library Handlers for Policy Injection Application Block&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;次に、処理を挟み込まれるターゲットのクラスを作成する。複雑なものにしてもしょうがないのでシンプルな感じにしてみた。&lt;/p&gt; &lt;p&gt; &lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:acc38e07-0f70-4855-9430-345ed0fd7283" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;public class Target : MarshalByRefObject
{
    public void Greet()
    {
        Console.WriteLine("Target.Greet Called.");
    }
}
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;PIABで処理を挟み込むクラスは、とりあえずMarshalByRefObjectを継承して作るらしい。&lt;br&gt;ほかにもインターフェースを実装するとかあるみたいだけど、とりあえず一番無難そうなMarshalByRefObjectにしてみたよ。&lt;/p&gt;
&lt;p&gt;次にMainを書いていく。Mainでは、PolicyInjectionというクラスを使ってTargetクラスのインスタンスを作ってGreetを呼び出している。&lt;/p&gt;
&lt;p&gt;
&lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:a7c711b7-39a8-4ff9-9cee-0597ad9009a3" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;class Program
{
    static void Main(string[] args)
    {
        // Targetクラスのインスタンスを作成して
        var target = PolicyInjection.Create&amp;lt;Target&amp;gt;();
        // 処理を呼び出す
        target.Greet();
    }
}
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;これが基本形みたい。実行結果は、まだ何も設定してないので「Target.Greet Called.」が表示されるだけ。&lt;br&gt;ここにプログラムをいじらずに処理を足しこんでみようと思う。&lt;/p&gt;
&lt;p&gt;まず、ログ出力をするのでLogging Application Blockの構成を行う。前やったのを参考に構成ファイルをぽちぽち組み立てる。&lt;br&gt;&lt;a href="http://kazuki.wankuma.com/images/2008/CEntLibPolicyInjectionApplicationBlock_17D/image.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="201" alt="image" src="http://kazuki.wankuma.com/images/2008/CEntLibPolicyInjectionApplicationBlock_17D/image_thumb.png" width="294" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;今回は、超シンプルにコンソールにログを吐くだけの構成にした。そのためSystem.Diagnostics TraceListenerを作って、TypeにSystem.Diagnostics.ConsoleTraceListenerを設定した。&lt;br&gt;そして、All Eventsに、そのTraceListenerを追加する。&lt;/p&gt;
&lt;p&gt;これで、すべてのログがコンソールに出るっていう寸法だ。確認のためMainを下のようにいじって実行結果を確認してみる。&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:05d6ce9b-6186-40f6-9eb1-32b906bfed5c" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;class Program
{
    static void Main(string[] args)
    {
        // Targetクラスのインスタンスを作成して
        var target = PolicyInjection.Create&amp;lt;Target&amp;gt;();
        // 処理を呼び出す
        target.Greet();

        // Logging Application Blockのテスト
        Logger.Write("Hello world");
    }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;br&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;u&gt;実行結果&lt;br&gt;&lt;/u&gt;&lt;/strong&gt;Target.Greet Called.&lt;br&gt;All Events Information: 1 : Timestamp: 2008/11/03 14:46:50&lt;br&gt;Message: Hello world&lt;br&gt;Category: General&lt;br&gt;Priority: -1&lt;br&gt;EventId: 1&lt;br&gt;Severity: Information&lt;br&gt;Title:&lt;br&gt;Machine: KAZUKI-PC&lt;br&gt;App Domain: PIABSampleApp.exe&lt;br&gt;ProcessId: 4152&lt;br&gt;Process Name: C:\Users\Kazuki\Documents\Visual Studio 2008\Projects\PIABSampleAp&lt;br&gt;p\PIABSampleApp\bin\Debug\PIABSampleApp.exe&lt;br&gt;Thread Name:&lt;br&gt;Win32 ThreadId:2400&lt;br&gt;Extended Properties:&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Logging Application Blockの構成が正しいのがわかったので、テスト用に追加したコードは消しておく。&lt;br&gt;次に本命のPolicy Injection Application Blockの構成に入る。&lt;/p&gt;
&lt;p&gt;Policy Injection Application Blockのセクションを追加。&lt;br&gt;&lt;a href="http://kazuki.wankuma.com/images/2008/CEntLibPolicyInjectionApplicationBlock_17D/image_3.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="93" alt="image" src="http://kazuki.wankuma.com/images/2008/CEntLibPolicyInjectionApplicationBlock_17D/image_thumb_3.png" width="244" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Policyを追加&lt;br&gt;&lt;a href="http://kazuki.wankuma.com/images/2008/CEntLibPolicyInjectionApplicationBlock_17D/image_4.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="61" alt="image" src="http://kazuki.wankuma.com/images/2008/CEntLibPolicyInjectionApplicationBlock_17D/image_thumb_4.png" width="244" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;MatchingRuleを追加。今回は、特定の型に対して処理を挟み込みたいのでType Matching Ruleを使う。&lt;br&gt;&lt;a href="http://kazuki.wankuma.com/images/2008/CEntLibPolicyInjectionApplicationBlock_17D/image_5.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="134" alt="image" src="http://kazuki.wankuma.com/images/2008/CEntLibPolicyInjectionApplicationBlock_17D/image_thumb_5.png" width="244" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Type Matching RuleのMatchesプロパティにPIABSampleApp.Targetを追加する。&lt;br&gt;&lt;a href="http://kazuki.wankuma.com/images/2008/CEntLibPolicyInjectionApplicationBlock_17D/image_6.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="169" alt="image" src="http://kazuki.wankuma.com/images/2008/CEntLibPolicyInjectionApplicationBlock_17D/image_thumb_6.png" width="244" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;HandlersにLogging handlerを追加する。&lt;br&gt;&lt;a href="http://kazuki.wankuma.com/images/2008/CEntLibPolicyInjectionApplicationBlock_17D/image_7.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="108" alt="image" src="http://kazuki.wankuma.com/images/2008/CEntLibPolicyInjectionApplicationBlock_17D/image_thumb_7.png" width="244" border="0"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Logging HandlerのAfterMessageとBeforeMessageに適当な文字列を設定する。&lt;br&gt;&lt;a href="http://kazuki.wankuma.com/images/2008/CEntLibPolicyInjectionApplicationBlock_17D/image_8.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="95" alt="image" src="http://kazuki.wankuma.com/images/2008/CEntLibPolicyInjectionApplicationBlock_17D/image_thumb_8.png" width="244" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;これで、App.configを保存してアプリケーションを再実行するとログがメソッド呼び出しの前後に入っているのがわかると思う。実行結果は、長いので省略して下に示します。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;u&gt;実行結果&lt;/u&gt;&lt;/strong&gt;&amp;nbsp;&lt;br&gt;All Events Information: 0 : Timestamp: 2008/11/03 14:54:21&lt;br&gt;Message: 前処理&lt;br&gt;// 省略&lt;br&gt;Target.Greet Called.&lt;br&gt;All Events Information: 0 : Timestamp: 2008/11/03 14:54:22&lt;br&gt;Message: 後処理&lt;br&gt;// 省略&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;こんな感じに、構成ファイルから任意のクラスのメソッドの呼び出しの前後に処理を挟み込むことが出来る。&lt;br&gt;MatchingRuleを変えることで、処理を挟み込む対象を変えたり、Handlerを変えることで挟み込む処理を変えることが出来るようになっている。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/kazuki/aggbug/160417.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>kazuki@wankuma.com (かずき)</dc:creator><title>[C#][EntLib]Logging Application Block その２ タイムスタンプをローカルの日時にしよう</title><link>http://blogs.wankuma.com/kazuki/archive/2008/11/02/160345.aspx</link><pubDate>Sun, 02 Nov 2008 10:38:00 GMT</pubDate><guid>http://blogs.wankuma.com/kazuki/archive/2008/11/02/160345.aspx</guid><wfw:comment>http://blogs.wankuma.com/kazuki/comments/160345.aspx</wfw:comment><comments>http://blogs.wankuma.com/kazuki/archive/2008/11/02/160345.aspx#Feedback</comments><slash:comments>13</slash:comments><wfw:commentRss>http://blogs.wankuma.com/kazuki/comments/commentRss/160345.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/kazuki/services/trackbacks/160345.aspx</trackback:ping><description>&lt;p&gt;Logging Application Blockで、デフォルトのまま使ってるとタイムスタンプがUTCになっている。&lt;br&gt;FormatterのTemplateに&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;Timestamp: {timestamp}&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;と書いてある部分がそれにあたる。&lt;br&gt;俺はグローバルな人じゃなくて日本人なんだぜ？って理由で日本時間でログを記載して欲しい場合は、この部分を下のように書き換えるといいみたい。 &lt;blockquote&gt; &lt;p&gt;Timestamp: {timestamp(local)}&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;めもめも。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/kazuki/aggbug/160345.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>kazuki@wankuma.com (かずき)</dc:creator><title>[WPF][C#][EntLib]UnityでAOP</title><link>http://blogs.wankuma.com/kazuki/archive/2008/11/02/160338.aspx</link><pubDate>Sun, 02 Nov 2008 02:01:00 GMT</pubDate><guid>http://blogs.wankuma.com/kazuki/archive/2008/11/02/160338.aspx</guid><wfw:comment>http://blogs.wankuma.com/kazuki/comments/160338.aspx</wfw:comment><comments>http://blogs.wankuma.com/kazuki/archive/2008/11/02/160338.aspx#Feedback</comments><slash:comments>47</slash:comments><wfw:commentRss>http://blogs.wankuma.com/kazuki/comments/commentRss/160338.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/kazuki/services/trackbacks/160338.aspx</trackback:ping><description>&lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/dd203099.aspx"&gt;Enterprise Library 4.1&lt;/a&gt;が出てた。&lt;br&gt;気になるのは、お気に入りのUnityContainerです。バージョンが1.2になるらしい。&lt;br&gt;その中でも、Policy Application Blockみたいな動きをするInterceptionというのが気になったのでつっついてみた。&lt;/p&gt; &lt;p&gt;AOPといえばロギング！！ということで、ロギングを例にしてみようと思う。まずは、土台作りから。&lt;br&gt;いつものに、ちょっぴり足したPersonクラスを作る。&lt;/p&gt; &lt;p&gt; &lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:e7b0987d-d386-432b-b65d-b5645e060dd0" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;namespace UnityEducation.Entities
{
    /// &amp;lt;summary&amp;gt;
    /// 挨拶できるよ
    /// &amp;lt;/summary&amp;gt;
    public interface IGreeter
    {
        /// &amp;lt;summary&amp;gt;
        /// 挨拶を返すよ
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;returns&amp;gt;挨拶の文字列&amp;lt;/returns&amp;gt;
        string Greet();
    }

    /// &amp;lt;summary&amp;gt;
    /// いつもの人間クラス
    /// &amp;lt;/summary&amp;gt;
    public class Person : IGreeter
    {
        /// &amp;lt;summary&amp;gt;
        /// 名前あるよ
        /// &amp;lt;/summary&amp;gt;
        public string Name { get; set; }

        /// &amp;lt;summary&amp;gt;
        /// 挨拶するよ
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;returns&amp;gt;名前入りの挨拶！&amp;lt;/returns&amp;gt;
        public string Greet()
        {
            return string.Format("{0}です！こんにちは！", Name);
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;このGreetメソッドにログを仕込むのが最終目標になる。&lt;br&gt;続いてMainメソッドで、単純にUnityContainerにPersonを登録して使うところの処理を書く。&lt;/p&gt;
&lt;p&gt;とりあえず、UnityContainerとInterceptionを使うのでObjectBuilder2とUnityとUnity.InterceptionExtensionをプロジェクトの参照に追加する。&lt;br&gt;&lt;a href="http://kazuki.wankuma.com/images/2008/WPFCEntLibUnityAOP_1C33/image.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="399" alt="image" src="http://kazuki.wankuma.com/images/2008/WPFCEntLibUnityAOP_1C33/image_thumb.png" width="565" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;そしてMainメソッドに処理を書いていく。&lt;/p&gt;
&lt;p&gt;
&lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:0f8ad67c-3216-4dfc-9a7c-48a650ac4314" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;using System;
using Microsoft.Practices.Unity;
using UnityEducation.Entities;

namespace UnityEducation
{
    class Program
    {
        static void Main(string[] args)
        {
            IUnityContainer c = new UnityContainer();

            // インスタンスをコンテナに登録
            c.RegisterInstance&amp;lt;IGreeter&amp;gt;(new Person { Name = "大田" });

            // インスタンスをコンテナから取得して挨拶文を表示
            var ohta = c.Resolve&amp;lt;IGreeter&amp;gt;();
            Console.WriteLine(ohta.Greet());
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;これを実行すると、下のようになる。&lt;br&gt;&lt;a href="http://kazuki.wankuma.com/images/2008/WPFCEntLibUnityAOP_1C33/image_3.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="91" alt="image" src="http://kazuki.wankuma.com/images/2008/WPFCEntLibUnityAOP_1C33/image_thumb_3.png" width="372" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;やっと土台が完成。これに処理を挟み込んでみようと思う。処理を挟み込むためには、２つのクラスを作らないといけない。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;HandlerAttributeを継承した属性&lt;br&gt;メソッドとハンドラを結びつけるための目印&lt;/li&gt;
&lt;li&gt;ICallHandlerを継承したクラス&lt;br&gt;挟み込む処理&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;まずは属性から。&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:8e633a5c-c27d-4fce-b666-cb964fcbd8c5" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;    /// &amp;lt;summary&amp;gt;
    /// ログを出力するためのAttribute
    /// &amp;lt;/summary&amp;gt;
    public class LoggingAttribute : HandlerAttribute
    {
        /// &amp;lt;summary&amp;gt;
        /// 挟み込む処理を返す
        /// &amp;lt;/summary&amp;gt;
        public override ICallHandler CreateHandler(IUnityContainer container)
        {
            return new LoggingHandler();
        }
    }
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これは、CreateHandlerメソッドをオーバーライドするだけでOK。返すものは、この後作るハンドラです。&lt;br&gt;ということで、ハンドラを作成する。&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:b107f41f-e6b0-4dfe-b274-06c4d0409042" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;/// &amp;lt;summary&amp;gt;
/// ログを出力するハンドラ
/// &amp;lt;/summary&amp;gt;
public class LoggingHandler : ICallHandler
{
    public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
    {
        Console.WriteLine("処理開始");
        try
        {
            // 処理を呼ぶ
            return getNext().Invoke(input, getNext);
        }
        finally
        {
            Console.WriteLine("処理終了");
        }
    }

    public int Order { get; set; }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ICallHandlerを継承して、Invokeメソッドを実装するだけでOK。最初と最後に処理の開始と終了のメッセージを出すようにしてみた。&lt;br&gt;実際のGreetメソッドの処理は、getNextデリゲートを呼ぶことで取得できる、getNext()の戻り値に対してInvokeメソッドを呼ぶと本来走る処理が実行される。（同じメソッドに複数のHandlerをセットしてたら別のHandlerの処理が呼ばれる）&lt;/p&gt;
&lt;p&gt;そして、PersonクラスのGreetメソッドにLoggingAttributeをセットする。&lt;/p&gt;
&lt;p&gt;
&lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:abe183bf-e783-467d-8dc4-90ef8957255e" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;/// &amp;lt;summary&amp;gt;
/// いつもの人間クラス
/// &amp;lt;/summary&amp;gt;
public class Person : IGreeter
{
    /// &amp;lt;summary&amp;gt;
    /// 名前あるよ
    /// &amp;lt;/summary&amp;gt;
    public string Name { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// 挨拶するよ
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;returns&amp;gt;名前入りの挨拶！&amp;lt;/returns&amp;gt;
    [Logging] // ログの処理を入れるよ
    public string Greet()
    {
        return string.Format("{0}です！こんにちは！", Name);
    }
}
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;最後にUnityContainerに対してInterceptionを使うということを示すコードを追加する。&lt;/p&gt;
&lt;p&gt;
&lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:e78cb72d-2325-4062-8c05-5a04c6515a7e" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;    class Program
    {
        static void Main(string[] args)
        {
            IUnityContainer c = new UnityContainer();

            // Interceptionの拡張を追加
            c.AddNewExtension&amp;lt;Interception&amp;gt;();

            // Interceptionの設定
            c.Configure&amp;lt;Interception&amp;gt;().
                // IGreeterにはTransparentProxyInterceptorを使います
                SetInterceptorFor&amp;lt;IGreeter&amp;gt;(new TransparentProxyInterceptor());

            // インスタンスをコンテナに登録
            c.RegisterInstance&amp;lt;IGreeter&amp;gt;(new Person { Name = "大田" });

            // インスタンスをコンテナから取得して挨拶文を表示
            var ohta = c.Resolve&amp;lt;IGreeter&amp;gt;();
            Console.WriteLine(ohta.Greet());
        }
    }
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;これを実行すると、さっきまでの挨拶一行以外に、処理開始と処理終了も出力されるようになる。&lt;br&gt;いい感じだ。&lt;br&gt;&lt;a href="http://kazuki.wankuma.com/images/2008/WPFCEntLibUnityAOP_1C33/image_4.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="106" alt="image" src="http://kazuki.wankuma.com/images/2008/WPFCEntLibUnityAOP_1C33/image_thumb_4.png" width="206" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;参考：&lt;a title="http://www.pnpguidance.net/Screencast/UnityInterceptionExtensionRemotingPolicyInjectorScreencastUnityTutorials.aspx" href="http://www.pnpguidance.net/Screencast/UnityInterceptionExtensionRemotingPolicyInjectorScreencastUnityTutorials.aspx"&gt;http://www.pnpguidance.net/Screencast/UnityInterceptionExtensionRemotingPolicyInjectorScreencastUnityTutorials.aspx&lt;/a&gt;&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/kazuki/aggbug/160338.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>kazuki@wankuma.com (かずき)</dc:creator><title>[EntLib][C#]IUnityContainerを拡張してしまおうぜ</title><link>http://blogs.wankuma.com/kazuki/archive/2008/07/31/151322.aspx</link><pubDate>Thu, 31 Jul 2008 23:17:00 GMT</pubDate><guid>http://blogs.wankuma.com/kazuki/archive/2008/07/31/151322.aspx</guid><wfw:comment>http://blogs.wankuma.com/kazuki/comments/151322.aspx</wfw:comment><comments>http://blogs.wankuma.com/kazuki/archive/2008/07/31/151322.aspx#Feedback</comments><slash:comments>26</slash:comments><wfw:commentRss>http://blogs.wankuma.com/kazuki/comments/commentRss/151322.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/kazuki/services/trackbacks/151322.aspx</trackback:ping><description>&lt;p&gt;Unityは、結構お気に入りになりそうな感じなんだけど、あまりいじれてない。UnityContainerは、UnityContainerExtensionというものを使って簡単に拡張？出来るようになっている。&lt;/p&gt; &lt;p&gt;ということで、早速やってみた。&lt;/p&gt; &lt;p&gt;下準備として、IUnityContainerに登録するクラス群を定義する。とりあえず単純な足し算引き算を行うクラスを作った。&lt;/p&gt; &lt;p&gt; &lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:46ec8b27-d90b-4284-b10f-b525c959f0db" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;    interface ICalc
    {
        int Execute(int lhs, int rhs);
    }
    class AddCalc : ICalc
    {
        public int Execute(int lhs, int rhs)
        {
            return lhs + rhs;
        }
    }
    class MinusCalc : ICalc
    {
        public int Execute(int lhs, int rhs)
        {
            return lhs - rhs;
        }
    }
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;計算というものをICalcとしてインターフェースにしてみたよ。まぁ、サンプルなんでこんなもんで。次に、UnityContainerExtensionを継承したクラスを定義する。Initializeというメソッドをオーバーライドすることになるので、ここにコンテナの初期化処理を書く。今回は、AddUnityContainerExtensionとMinusUnityContainerExtensionを定義した。&lt;br&gt;上で作ったICalcやAddCalc,MinusCalcをUnityContainerに追加するためのクラスとして使える。&lt;/p&gt;
&lt;p&gt;
&lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:7f9ee9fd-3ba5-48d7-9e8d-f64b714eab82" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;    // 計算といえば足し算用でしょ拡張
    class AddUnityContainerExtension : UnityContainerExtension
    {
        protected override void Initialize()
        {
            Container.RegisterType&amp;lt;ICalc, AddCalc&amp;gt;();
        }
    }

    // 計算といえば引き算でしょ拡張
    class MinusUnityContainerExtension : UnityContainerExtension
    {
        protected override void Initialize()
        {
            Container.RegisterType&amp;lt;ICalc, MinusCalc&amp;gt;();
        }
    }
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;UnityContainerExtensionにはContainerというプロパティが定義されているので、Containerプロパティを通じてUnityContainerにアクセスしている。ここで作ったUnityContainerExtensionは、AddNewExtensionメソッドを使ってUnityContainerに設定できるようになっている。&lt;/p&gt;
&lt;p&gt;要は、各々のExtensionを追加することで、関連のあるものをUnityContainerに一括で登録できてしまうといったものみたいだ。早速作ったものを使ってみようと思う。&lt;/p&gt;
&lt;p&gt;その前に、ICalcを使うクラスを定義してみた。&lt;/p&gt;
&lt;p&gt;
&lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:1e1abdf6-ad6a-489a-8bf4-15322f6738b6" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;class CalcClient
{
    [Dependency]
    public ICalc Calc { get; set; }

    public void Execute()
    {
        Console.WriteLine(Calc.Execute(10, 3));
    }
}
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;計算して出力するだけ！シンプル。&lt;/p&gt;
&lt;p&gt;長かったけど、やっとUnityContainerを使うよ！といってもコードは数行…&lt;/p&gt;
&lt;p&gt;
&lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:5243567e-dfcc-453b-a291-382e41e24c28" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;// コンテナを作って
var c = new UnityContainer();
// 足し算の計算用に拡張？して
c.AddNewExtension&amp;lt;AddUnityContainerExtension&amp;gt;();

// CalcClientをコンテナ経由で取得
c.RegisterType&amp;lt;CalcClient, CalcClient&amp;gt;();
var client = c.Resolve&amp;lt;CalcClient&amp;gt;();
client.Execute(); // -&amp;gt; 13
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;これを実行すると、10 + 3なので13と表示される。AddNewExtensionの部分をMinusUnityContainerExtensionに変更すると7 と表示される。&lt;/p&gt;
&lt;p&gt;
&lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:563ec85c-df35-4937-87be-0a07a623e4dd" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;// コンテナを作って
var c = new UnityContainer();
// 引き算の計算用に拡張？して
c.AddNewExtension&amp;lt;MinusUnityContainerExtension&amp;gt;();

// CalcClientをコンテナ経由で取得
c.RegisterType&amp;lt;CalcClient, CalcClient&amp;gt;();
var client = c.Resolve&amp;lt;CalcClient&amp;gt;();
client.Execute(); // -&amp;gt; 7
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;今回のサンプルでは、一種類しかクラスを登録していなかったからありがたみは無いかもしれないけど、たとえばフレームワーク等で、関連のあるクラス群を一気に登録してしまおうというときにいいかもしれない。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/kazuki/aggbug/151322.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>kazuki@wankuma.com (かずき)</dc:creator><title>[C#][EntLib]Logging Application Block その１「とりあえず使ってみよう」</title><link>http://blogs.wankuma.com/kazuki/archive/2008/07/22/149795.aspx</link><pubDate>Tue, 22 Jul 2008 22:39:00 GMT</pubDate><guid>http://blogs.wankuma.com/kazuki/archive/2008/07/22/149795.aspx</guid><wfw:comment>http://blogs.wankuma.com/kazuki/comments/149795.aspx</wfw:comment><comments>http://blogs.wankuma.com/kazuki/archive/2008/07/22/149795.aspx#Feedback</comments><slash:comments>381</slash:comments><wfw:commentRss>http://blogs.wankuma.com/kazuki/comments/commentRss/149795.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/kazuki/services/trackbacks/149795.aspx</trackback:ping><description>&lt;p&gt;Unityが、いい感じのDIコンテナっぽい。&lt;br&gt;ということで、ほかのApplication Blockもぼちぼちいじってみようと思う。どれから使おうか悩んだけど、一番手軽に使えそうなものとして、Logging Application Blockを選んでみた。&lt;br&gt;EntLib4.0のLoggingの情報をWebで探してみたけど、簡単に探した範囲内だと、見つけきらなかったので泣く泣く英語のドキュメントを見ながられっつトライ！！&lt;/p&gt; &lt;p&gt;とりあえず、お試しのためにConsole Applicationのプロジェクトを１つ追加する。名前はLoggingTestにした。ここに、色々追加していってファイルにログを出力するようにしてみようと思う。&lt;/p&gt; &lt;h1&gt;参照の追加&lt;/h1&gt; &lt;ol&gt; &lt;li&gt;Enterprise Library&amp;nbsp; Application Block  &lt;li&gt;Enterprise Library&amp;nbsp; Shared Library  &lt;li&gt;Microsoft.Practices.ObjectBuilder2&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;この３つを参照に追加する。&lt;/p&gt; &lt;h1&gt;&lt;/h1&gt; &lt;h1&gt;App.configの編集&lt;/h1&gt; &lt;p&gt;App.configにLogging Application Blockの設定を追加する。&lt;br&gt;log4netしかりs2.netしかり、こういうのは一番メンドクサイところでもある。俺様フレームワークでも、きっとApp.configにごにょごにょして…という感じに作ってしまいそう（というか、それが正当だしね）だ。しかし、EnterpriseLibraryでは、専用の編集ツールがついてきているので、めんどくささはあまり感じない。&lt;br&gt;GUIでの編集万歳！ということでぽちぽちします。&lt;/p&gt; &lt;ol&gt; &lt;li&gt;新規作成でアプリケーション構成ファイル（App.config）を追加する。  &lt;li&gt;ソリューションエクスプローラで、App.configの右クリックメニューからEdit Enterprise Library Configurationを選ぶ&lt;br&gt;&lt;a href="http://kazuki.wankuma.com/images/2008/04/CEntLibLoggingApplicationBlock_81AE/image.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="91" alt="image" src="http://kazuki.wankuma.com/images/2008/04/CEntLibLoggingApplicationBlock_81AE/image_thumb.png" width="244" border="0"&gt;&lt;/a&gt;  &lt;li&gt;Logging Application Blockを追加する&lt;br&gt;&lt;a href="http://kazuki.wankuma.com/images/2008/04/CEntLibLoggingApplicationBlock_81AE/image_3.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="73" alt="image" src="http://kazuki.wankuma.com/images/2008/04/CEntLibLoggingApplicationBlock_81AE/image_thumb_3.png" width="244" border="0"&gt;&lt;/a&gt;  &lt;li&gt;Trace ListenersにFlat File Trace Listenerを追加する&lt;br&gt;&lt;a href="http://kazuki.wankuma.com/images/2008/04/CEntLibLoggingApplicationBlock_81AE/image_4.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="65" alt="image" src="http://kazuki.wankuma.com/images/2008/04/CEntLibLoggingApplicationBlock_81AE/image_thumb_4.png" width="244" border="0"&gt;&lt;/a&gt;  &lt;li&gt;FlatFile TraceListenerのプロパティを編集する。&lt;br&gt;保存するファイル名は、デフォルトでtrace.logになっているので、そのまま利用する。&lt;br&gt;Formatterプロパティには、Logging Application Blockを追加したときに作られているText Formatterを指定する。&lt;br&gt;&lt;a href="http://kazuki.wankuma.com/images/2008/04/CEntLibLoggingApplicationBlock_81AE/image_5.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="156" alt="image" src="http://kazuki.wankuma.com/images/2008/04/CEntLibLoggingApplicationBlock_81AE/image_thumb_5.png" width="244" border="0"&gt;&lt;/a&gt;  &lt;li&gt;Special SourcesのAll EventsにTraceListener Referenceを追加する。  &lt;li&gt;TraceListener ReferenceのReferencedTraceListenerに、４で作ったFlatFile TraceListenerを設定する。&lt;br&gt;&lt;a href="http://kazuki.wankuma.com/images/2008/04/CEntLibLoggingApplicationBlock_81AE/image_6.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="137" alt="image" src="http://kazuki.wankuma.com/images/2008/04/CEntLibLoggingApplicationBlock_81AE/image_thumb_6.png" width="244" border="0"&gt;&lt;/a&gt;  &lt;li&gt;保存してApp.configを閉じる&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;これで、Logging Application BlockのAPIを使ってログを出力すると問答無用でtrace.logに出力されるようになるはず。&lt;br&gt;個人的な理解としては&lt;/p&gt; &lt;ul&gt; &lt;li&gt;～Listenerでどこに出力するか決める  &lt;li&gt;～Formatterで、どういう書式で出力するか決める  &lt;li&gt;～Sourcesで、どういう時に、どのListenerを使うか決める  &lt;li&gt;～Filter（今回はつかってない）で、出力するログをフィルタリングする&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;くらいだと思ってる。TOEIC285点の英語力でなんとなく思ったことなので間違ってる可能性が非常に高いので、間違ってたら誰か指摘していただきたい。&lt;/p&gt; &lt;h1&gt;APIを使ってログを出力する&lt;/h1&gt; &lt;p&gt;ついに楽しいプログラミング！！&lt;br&gt;Program.csにHello worldというログを出力するプログラムを書いていく。といってもとっても簡単。説明をする前にプログラムをさくっと乗せてみる。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:bd60dee0-d888-41cc-a5db-5141c09097e0" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;using Microsoft.Practices.EnterpriseLibrary.Logging;

namespace LoggingTest
{
    class Program
    {
        static void Main(string[] args)
        {
            // メッセージがHello worldのログエントリ
            var logEntry = new LogEntry
            {
                Message = "Hello world"
            };

            // ログエントリを出力
            Logger.Write(logEntry);
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;これを実行すると、exeと同じフォルダにtrace.logというファイルが出来上がる。内容は下のような感じ。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;----------------------------------------&lt;br&gt;Timestamp: 2008/07/20 2:15:16&lt;br&gt;Message: Hello world&lt;br&gt;Category: General&lt;br&gt;Priority: -1&lt;br&gt;EventId: 0&lt;br&gt;Severity: Information&lt;br&gt;Title:&lt;br&gt;Machine: KAZUKI-PC2&lt;br&gt;Application Domain: LoggingTest.exe&lt;br&gt;Process Id: 5748&lt;br&gt;Process Name: C:\Users\Kazuki\Documents\Visual Studio 2008\Projects\LoggingTest\LoggingTest\bin\Debug\LoggingTest.exe&lt;br&gt;Win32 Thread Id: 1144&lt;br&gt;Thread Name: &lt;br&gt;Extended Properties: &lt;br&gt;----------------------------------------&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Messageに、プログラムから指定したHello worldの文字列があるのがわかる。ここに列挙されているProirityやEventIdなんかも、LogEntryのプロパティとして用意されているので、プログラム上から指定すれば任意の値を設定することが出来るようになってる。&lt;/p&gt;
&lt;p&gt;例えば、Titleを指定してログを出力する場合は下のようになる。&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:01ba254a-391d-4295-9fb2-57a1db2208be" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;var logEntry = new LogEntry
{
    Title = "たいとる",
    Message = "Hello world"
};
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;このLogEntryを出力すると、下のようなログがファイルに保存される。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;----------------------------------------&lt;br&gt;Timestamp: 2008/07/20 2:28:20&lt;br&gt;Message: Hello world&lt;br&gt;Category: General&lt;br&gt;Priority: -1&lt;br&gt;EventId: 0&lt;br&gt;Severity: Information&lt;br&gt;Title:たいとる&lt;br&gt;Machine: KAZUKI-PC2&lt;br&gt;Application Domain: LoggingTest.exe&lt;br&gt;Process Id: 4872&lt;br&gt;Process Name: C:\Users\Kazuki\Documents\Visual Studio 2008\Projects\LoggingTest\LoggingTest\bin\Debug\LoggingTest.exe&lt;br&gt;Win32 Thread Id: 4756&lt;br&gt;Thread Name: &lt;br&gt;Extended Properties: &lt;br&gt;----------------------------------------&lt;/p&gt;&lt;/blockquote&gt;&lt;img src ="http://blogs.wankuma.com/kazuki/aggbug/149795.aspx" width = "1" height = "1" /&gt;</description></item></channel></rss>