<?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>MEF</title><link>http://blogs.wankuma.com/kazuki/category/2158.aspx</link><description>MEF</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>k.ota.0130@gmail.com(かずき)</dc:creator><title>[MEF][WPF]XAMLからMEFのコンテナにアクセスするマークアップ拡張</title><link>http://blogs.wankuma.com/kazuki/archive/2010/01/29/185533.aspx</link><pubDate>Fri, 29 Jan 2010 01:11:00 GMT</pubDate><guid>http://blogs.wankuma.com/kazuki/archive/2010/01/29/185533.aspx</guid><wfw:comment>http://blogs.wankuma.com/kazuki/comments/185533.aspx</wfw:comment><comments>http://blogs.wankuma.com/kazuki/archive/2010/01/29/185533.aspx#Feedback</comments><slash:comments>239</slash:comments><wfw:commentRss>http://blogs.wankuma.com/kazuki/comments/commentRss/185533.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/kazuki/services/trackbacks/185533.aspx</trackback:ping><description>&lt;p&gt;何となく作ってみた。 &lt;p&gt;まず、コンテナを保持しておくためのstaticなクラスを用意する。 &lt;p&gt;&lt;a href="http://d.hatena.ne.jp/okazuki/20100128/1264694978"&gt;続きを読む&lt;/a&gt;&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/kazuki/aggbug/185533.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>k.ota.0130@gmail.com(かずき)</dc:creator><title>[WPF][C#][MEF]MEF(Managed Extensibility Framework) &amp;amp; WPFでHello world</title><link>http://blogs.wankuma.com/kazuki/archive/2009/12/05/183557.aspx</link><pubDate>Sat, 05 Dec 2009 01:05:00 GMT</pubDate><guid>http://blogs.wankuma.com/kazuki/archive/2009/12/05/183557.aspx</guid><wfw:comment>http://blogs.wankuma.com/kazuki/comments/183557.aspx</wfw:comment><comments>http://blogs.wankuma.com/kazuki/archive/2009/12/05/183557.aspx#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://blogs.wankuma.com/kazuki/comments/commentRss/183557.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/kazuki/services/trackbacks/183557.aspx</trackback:ping><description>&lt;p&gt;注意：MEFは、正式リリース前のbeta版を使ってるので、正式版とは違うかもしれません。 &lt;p&gt;次期.NET Framework4に入るDIコンテナのMEFとWPFを組み合わせて、簡単なHello worldを作ってみようと思います。 &lt;p&gt;&lt;a href="http://d.hatena.ne.jp/okazuki/20091204/1259942620"&gt;続きを読む&lt;/a&gt;&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/kazuki/aggbug/183557.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>kazuki@wankuma.com (かずき)</dc:creator><title>[Silverlight][MEF]MEFのbeta2(preview 7)が出てました</title><link>http://blogs.wankuma.com/kazuki/archive/2009/09/11/181133.aspx</link><pubDate>Fri, 11 Sep 2009 12:40:00 GMT</pubDate><guid>http://blogs.wankuma.com/kazuki/archive/2009/09/11/181133.aspx</guid><wfw:comment>http://blogs.wankuma.com/kazuki/comments/181133.aspx</wfw:comment><comments>http://blogs.wankuma.com/kazuki/archive/2009/09/11/181133.aspx#Feedback</comments><slash:comments>10</slash:comments><wfw:commentRss>http://blogs.wankuma.com/kazuki/comments/commentRss/181133.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/kazuki/services/trackbacks/181133.aspx</trackback:ping><description>&lt;p&gt;ぽろっと覗きに行ったら、MEF Preview 7が出てました。↓からダウンロードできます。&lt;br&gt;&lt;a title="http://mef.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=30259" href="http://mef.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=30259"&gt;http://mef.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=30259&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Preview 6がどうだったか覚えてませんが、今回は.net 3.5で動くものと、Silverlight3で動くものを別々にダウンロードしないといけないみたいです。&lt;/p&gt; &lt;p&gt;このMEFは、次バージョンの.NET Framework 4.0にのると思う（情報のソースは忘れました！）ので、勉強しておいて損はない一品だと思います。&lt;br&gt;というか、言語の標準ライブラリにDIコンテナがついてくるのは、.NETが初？？（.NETは言語じゃね～っていう突っ込みはしないでね♪）&lt;/p&gt; &lt;p&gt;JavaやRubyやPerlやJavaScriptやC++やHaskellには、少なくともついてない！！&lt;br&gt;これは、アツイ。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/kazuki/aggbug/181133.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>kazuki@wankuma.com (かずき)</dc:creator><title>[C#][MEF]Managed Extensibility Framework入門 その８</title><link>http://blogs.wankuma.com/kazuki/archive/2009/07/10/177316.aspx</link><pubDate>Fri, 10 Jul 2009 01:38:00 GMT</pubDate><guid>http://blogs.wankuma.com/kazuki/archive/2009/07/10/177316.aspx</guid><wfw:comment>http://blogs.wankuma.com/kazuki/comments/177316.aspx</wfw:comment><comments>http://blogs.wankuma.com/kazuki/archive/2009/07/10/177316.aspx#Feedback</comments><slash:comments>12</slash:comments><wfw:commentRss>http://blogs.wankuma.com/kazuki/comments/commentRss/177316.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/kazuki/services/trackbacks/177316.aspx</trackback:ping><description>&lt;p&gt;&lt;strong&gt;&lt;u&gt;過去の関連記事&lt;/u&gt;&lt;/strong&gt;&lt;br&gt;&lt;a href="http://blogs.wankuma.com/kazuki/archive/2009/06/30/176822.aspx"&gt;[C#][MEF]Managed Extensibility Framework入門 その１&lt;/a&gt;&lt;br&gt;&lt;a href="http://blogs.wankuma.com/kazuki/archive/2009/06/30/176825.aspx"&gt;[C#][MEF]Managed Extensibility Framework入門 その２&lt;/a&gt;&lt;br&gt;&lt;a href="http://blogs.wankuma.com/kazuki/archive/2009/07/01/176869.aspx"&gt;[C#][MEF]Managed Extensibility Framework入門 その３&lt;/a&gt;&lt;br&gt;&lt;a href="http://blogs.wankuma.com/kazuki/archive/2009/07/02/176927.aspx"&gt;[C#][MEF]Managed Extensibility Framework入門 その４&lt;/a&gt;&lt;br&gt;&lt;a href="http://blogs.wankuma.com/kazuki/archive/2009/07/02/176950.aspx"&gt;[C#][MEF]Managed Extensibility Framework入門 その５&lt;/a&gt;&lt;br&gt;&lt;a href="http://blogs.wankuma.com/kazuki/archive/2009/07/03/177013.aspx"&gt;[C#][MEF]Managed Extensibility Framework入門 その６&lt;/a&gt;&lt;br&gt;&lt;a href="http://blogs.wankuma.com/kazuki/archive/2009/07/05/177095.aspx"&gt;[C#][MEF]Managed Extensibility Framework入門 その７&lt;/a&gt; &lt;p&gt;前回に引き続き、Catalog関連の部分をやってみようと思います。&lt;br&gt;今回のターゲットはDirectoryCatalogです。 &lt;p&gt;こいつは、Directory内にあるアセンブリを自動で読み取って登録してくれるものです。&lt;br&gt;ということで、いつもどおりのコンソールアプリケーションにも飽きてきたので、WPFアプリケーションで実験してみようと思います。 &lt;p&gt;WpfMEFという名前でWPFアプリケーションを作成します。&lt;br&gt;そして、Window1にExport属性をつけてコンテナにExportします。&lt;/p&gt; &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:4e8e46d2-3416-46f5-8ad0-184236f7f0c0" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;[Export]
public partial class Window1 : Window
{
	// 省略
}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;そして、App.xamlのStartupUri属性を消してStartupイベントを作り、そこに以下のようなコンテナの初期化コードと、Window1を表示する処理を書きます。&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:1a2e9ed1-67fb-43df-b5e4-1dd03b5de981" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Windows;

namespace WpfMEF
{
    public partial class App : Application
    {
        private void Application_Startup(object sender, StartupEventArgs e)
        {
            // カレントディレクトリにあるアセンブリを対象にするDirectoryCatalogを作成
            var dirCatalog = new DirectoryCatalog(".");
            // 自アセンブリと↑をまとめたカタログを作成
            var catalog = new AggregateCatalog(
                new AssemblyCatalog(typeof(App).Assembly),
                dirCatalog);

            // コンテナを作成してDirectoryCatalogを明示的にコンテナに追加
            var con = new CompositionContainer(catalog);
            var batch = new CompositionBatch();
            batch.AddExportedObject&amp;lt;DirectoryCatalog&amp;gt;(dirCatalog);
            con.Compose(batch);

            // Window1を表示
            var window = con.GetExportedObject&amp;lt;Window1&amp;gt;();
            window.Show();
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;今回のキモは、DirectoryCatalogをあえてコンテナに登録しているところです。&lt;br&gt;こうすることで、DirectoryCatalogをImportできるようになります。&lt;/p&gt;
&lt;p&gt;次に、Window1.xamlを編集していきます。Window1.xamlは、プラグインをホストするためのItemsControlと、プラグインの再読み込みを行うRefreshボタンがあるだけのシンプル構造にしました。&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:4cec28b6-eb5f-4207-9400-625ca696b0d1" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="xml"&gt;&amp;lt;Window x:Class="WpfMEF.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Loaded="Window_Loaded"
    Title="Window1"&amp;gt;
    &amp;lt;DockPanel&amp;gt;
        &amp;lt;Button DockPanel.Dock="Top" Content="Refresh" Click="Button_Click" /&amp;gt;
        &amp;lt;ItemsControl ItemsSource="{Binding Plugins}"/&amp;gt;
    &amp;lt;/DockPanel&amp;gt;
&amp;lt;/Window&amp;gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Window1のイベントとしては、Loadedイベントと、Refreshボタンのクリックイベントを登録しています。Loadedイベントとクリックイベントでは、プラグインの再読み込みを行っています。&lt;/p&gt;
&lt;p&gt;コードとしては、こんな感じです。&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:b08bbe31-1dba-49c1-8d8e-9d878ba92b13" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;using System.Collections.ObjectModel;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Windows;

namespace WpfMEF
{
    [Export]
    public partial class Window1 : Window
    {
        // プラグイン
        [Import(AllowRecomposition=true)]
        public ExportCollection&amp;lt;FrameworkElement&amp;gt; ExportedFrameworkElements { get; set; }

        // カタログ
        [Import]
        public DirectoryCatalog Catalog { get; set; }

        // ここにプラグインに定義されたFrameworkElementが入る.
        // XAML側のItemsControlとバインドされているので、ここに入れたFrameworkElementが画面に
        // 表示される。
        public ObservableCollection&amp;lt;FrameworkElement&amp;gt; Plugins { get; private set; }

        // プラグインの初期化・再読み込みを行う
        private void LoadPlugins()
        {
            // 初回のときはコレクションを作成する
            if (Plugins == null)
            {
                this.Plugins = new ObservableCollection&amp;lt;FrameworkElement&amp;gt;();
            }

            // 再読み込み開始
            Catalog.Refresh();
            Plugins.Clear();

            // 新たなプラグインをコレクションに追加
            foreach(var plugin in ExportedFrameworkElements)
            {
                Plugins.Add(plugin.GetExportedObject());
            }
        }

        public Window1()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            LoadPlugins();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            LoadPlugins();

            // とりあえずコードビハインドがViewModel役
            DataContext = this;
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これで、プラグインをホストする側は完成です。&lt;br&gt;実行すると、ボタンがあるだけの悲しい画面が起動するのが確認できます。&lt;/p&gt;
&lt;h1&gt;プラグインを作成&lt;/h1&gt;
&lt;p&gt;プラグインのプロジェクトを２つ作成します。WpfPlugin1とWpfPlugin2という名前でWPFのユーザコントロールライブラリを作成します。System.ComponentModel.Composition.dllへの参照を各々追加しておきます。&lt;br&gt;それぞれ、非常にシンプルなユーザコントロールを１つずつ定義しておきます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;u&gt;Plugin1のほうのユーザコントロール&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:3ceb9596-be88-4343-aa1b-b15d8b3a2074" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="xml"&gt;&amp;lt;UserControl x:Class="WpfPlugin1.Plugin1Control"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&amp;gt;
    &amp;lt;Grid&amp;gt;
        &amp;lt;TextBlock Text="Plugin1" /&amp;gt;
    &amp;lt;/Grid&amp;gt;
&amp;lt;/UserControl&amp;gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;&lt;u&gt;Plugin2のほうのユーザコントロール&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:00164357-4bac-4c07-8539-ee9efff873ea" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="xml"&gt;&amp;lt;UserControl x:Class="WpfPlugin2.UserControl1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&amp;gt;
    &amp;lt;Grid&amp;gt;
        &amp;lt;TextBlock Text="Plugin2" /&amp;gt;
    &amp;lt;/Grid&amp;gt;
&amp;lt;/UserControl&amp;gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;各々のコードビハインドで、クラスにExport(typeof(FrameworkElement))属性をつけます。&lt;br&gt;こうすることで、プラグインをホストする側のExportCollection&amp;lt;FrameworkElement&amp;gt;にImportされるようになります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;u&gt;Plugin1のほうのコードビハインド&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:47e6ecbd-3b88-4de6-a03c-5e3478bf403b" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;using System.ComponentModel.Composition;
using System.Windows;
using System.Windows.Controls;

namespace WpfPlugin1
{
    [Export(typeof(FrameworkElement))]
    public partial class Plugin1Control : UserControl
    {
        public Plugin1Control()
        {
            InitializeComponent();
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;u&gt;Plugin2のほうのコードビハインド&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:8453439c-7443-4f0d-96b9-e60688d5903b" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;using System.ComponentModel.Composition;
using System.Windows;
using System.Windows.Controls;

namespace WpfPlugin2
{
    [Export(typeof(FrameworkElement))]
    public partial class UserControl1 : UserControl
    {
        public UserControl1()
        {
            InitializeComponent();
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;それでは、実行して動きを見ていきます。&lt;br&gt;WpfMEFを起動してボタン１つだけの画面が起動することを確認します。&lt;br&gt;&lt;a href="http://kazuki.wankuma.com/images/2009/CMEFManagedExtensibilityFramework_1414/image.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://kazuki.wankuma.com/images/2009/CMEFManagedExtensibilityFramework_1414/image_thumb.png" width="244" height="191"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;アプリケーションをいったん終了して、WpfMEFのbin\Debugフォルダに、WpfPlugin1.dllをコピーして起動します。&lt;br&gt;すると、画面にPlugin1が表示されます。&lt;br&gt;&lt;a href="http://kazuki.wankuma.com/images/2009/CMEFManagedExtensibilityFramework_1414/image_3.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://kazuki.wankuma.com/images/2009/CMEFManagedExtensibilityFramework_1414/image_thumb_3.png" width="242" height="225"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;続いて、起動したままの状態でWpfPlugin2.dllをWpfEMFのbin\DebugフォルダにコピーしてRefreshボタンを押すと…&lt;br&gt;&lt;a href="http://kazuki.wankuma.com/images/2009/CMEFManagedExtensibilityFramework_1414/image_4.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://kazuki.wankuma.com/images/2009/CMEFManagedExtensibilityFramework_1414/image_thumb_4.png" width="244" height="207"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Plugin2が追加されました！&lt;br&gt;ということで、DirectoryCatalogを使うと、プラグインみたいな機能が割りと簡単に作れるということでした。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/kazuki/aggbug/177316.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>kazuki@wankuma.com (かずき)</dc:creator><title>[C#][MEF]Managed Extensibility Framework入門 その７</title><link>http://blogs.wankuma.com/kazuki/archive/2009/07/05/177095.aspx</link><pubDate>Sun, 05 Jul 2009 11:46:00 GMT</pubDate><guid>http://blogs.wankuma.com/kazuki/archive/2009/07/05/177095.aspx</guid><wfw:comment>http://blogs.wankuma.com/kazuki/comments/177095.aspx</wfw:comment><comments>http://blogs.wankuma.com/kazuki/archive/2009/07/05/177095.aspx#Feedback</comments><slash:comments>22</slash:comments><wfw:commentRss>http://blogs.wankuma.com/kazuki/comments/commentRss/177095.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/kazuki/services/trackbacks/177095.aspx</trackback:ping><description>&lt;p&gt;&lt;strong&gt;&lt;u&gt;過去の関連記事&lt;/u&gt;&lt;/strong&gt;&lt;br&gt;&lt;a href="http://blogs.wankuma.com/kazuki/archive/2009/06/30/176822.aspx"&gt;[C#][MEF]Managed Extensibility Framework入門 その１&lt;/a&gt;&lt;br&gt;&lt;a href="http://blogs.wankuma.com/kazuki/archive/2009/06/30/176825.aspx"&gt;[C#][MEF]Managed Extensibility Framework入門 その２&lt;/a&gt;&lt;br&gt;&lt;a href="http://blogs.wankuma.com/kazuki/archive/2009/07/01/176869.aspx"&gt;[C#][MEF]Managed Extensibility Framework入門 その３&lt;/a&gt;&lt;br&gt;&lt;a href="http://blogs.wankuma.com/kazuki/archive/2009/07/02/176927.aspx"&gt;[C#][MEF]Managed Extensibility Framework入門 その４&lt;/a&gt;&lt;br&gt;&lt;a href="http://blogs.wankuma.com/kazuki/archive/2009/07/02/176950.aspx"&gt;[C#][MEF]Managed Extensibility Framework入門 その５&lt;/a&gt;&lt;br&gt;&lt;a href="http://blogs.wankuma.com/kazuki/archive/2009/07/03/177013.aspx"&gt;[C#][MEF]Managed Extensibility Framework入門 その６&lt;/a&gt;&lt;/p&gt; &lt;p&gt;MEF入門も、既に7回目になりました。&lt;br&gt;あと何個か書くネタがありますが、今回は今までと趣向を変えてCatalogについてちょっと試してみようと思います。  &lt;h1&gt;同一アセンブリしか駄目なの？&lt;/h1&gt; &lt;p&gt;いきなり変なタイトルをつけましたが、今までのサンプルは、AssemblyCatalogというクラスを使ってコンテナを作成していました。このAssemblyCatalogは、引数で指定したアセンブリの中からExport属性やImport属性のついたものを自動的に収集してくれるいい奴です。&lt;/p&gt; &lt;p&gt;ただ、これだと１つのアセンブリからしかクラスを取得できません。&lt;br&gt;後は、第二回で使ったCompositionBatchを使って１つ１つ登録しないといけないみたいに感じてしまいますが、そんなことはありません。&lt;/p&gt; &lt;p&gt;ちゃんと、他にも～Catalogクラスがあります。&lt;/p&gt; &lt;h1&gt;Catalog系クラス達&lt;/h1&gt; &lt;p&gt;Catalog系というのも今勝手につけた言い方ですが、～Catalogという名前のクラスを４つ紹介したいと思います。&lt;/p&gt; &lt;ol&gt; &lt;li&gt;System.ComponentModel.Composition.Hosting.TypeCatalog&lt;br&gt;名前からわかるとおり、指定された型を対象にするカタログクラスです。  &lt;li&gt;System.ComponentModel.Composition.Hosting.AssemblyCatalog&lt;br&gt;今までお世話になってきた、指定したアセンブリ内のクラスを対象にするカタログクラスです。  &lt;li&gt;System.ComponentModel.Composition.Hosting.DirectoryCatalog&lt;br&gt;こいつが今回の大本命です。&lt;br&gt;指定したディレクトリ内にあるアセンブリを勝手に読み込んでくれます。うわさによると、実行中に追加されたDLLも認識するとか・・・。  &lt;li&gt;System.ComponentModel.Composition.Hosting.AggregateCatalog&lt;br&gt;複数のCatalogを一まとめにする縁の下の力持ち&lt;/li&gt;&lt;/ol&gt; &lt;h2&gt;TypeCatalog&lt;/h2&gt; &lt;p&gt;TypeCatalogは、コンストラクタで渡したTypeを対象にするクラスです。何かフレームワークとかで決まった型を登録したいとかいうときに使いそう？&lt;/p&gt; &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:63ba4400-680f-44ab-9ce4-ead0e5def42b" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;

namespace MEFCatalog
{
    [Export]
    public class Greeter
    {
        public string Greet()
        {
            return "Hello world";
        }
    }

    [Export]
    public class GreetApp
    {
        [Import]
        public Greeter Greeter { get; set; }

        public void Execute()
        {
            Console.WriteLine(Greeter.Greet());
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            // TypeCatalogにGreeterとGreetAppを登録
            var typeCatalog = new TypeCatalog(
                typeof(Greeter), typeof(GreetApp));
            // TypeCatalogでContainerを作成
            var container = new CompositionContainer(typeCatalog);

            // 後はいつもどおり
            var app = container.GetExportedObject&amp;lt;GreetApp&amp;gt;();
            app.Execute();
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;このコードでHello worldが表示されます。&lt;/p&gt;
&lt;h2&gt;AssemblyCatalog&lt;/h2&gt;
&lt;p&gt;これまでのサンプルの通りなので省略&lt;/p&gt;
&lt;h1&gt;AggregateCatalog&lt;/h1&gt;
&lt;p&gt;AggregateCatalogは、複数のCatalogを１まとめにするために使います。&lt;br&gt;例えば、AssemblyCatalogとTypeCatalogを１まとめにして、コンテナに渡す場合は下のようになります。&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:c67eaa50-0533-400f-8385-937fe2a8f541" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;// 型A, B, Cを登録するよ
var typeCatalog = new TypeCatalog(
  typeof(A), typeof(B), typeof(C));

// 型Programのあるアセンブリ内のクラスを登録するよ
var assmCatalog = new AssemblyCatalog(
  typeof(Program).Assembly);

// typeCatalogとassmCatalogを１まとめに
var aggCatalog = new AggregateCatalog(
  typeCatalog, assmCatalog);

// typeCatalogとassmCatalogにある両方の型が登録されたコンテナの完成
var container = new CompositionContainer(aggCatalog);&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;CompositionContainerが、Catalogを１つしか受け取らないので、複数のCatalogを使いたいときは、AggregateCatalogで事前に１まとめにしておく必要があるようです。&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;DirectoryCatalogについては、また次回で(時間切れ)！&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/kazuki/aggbug/177095.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>kazuki@wankuma.com (かずき)</dc:creator><title>[C#][MEF]Managed Extensibility Framework入門 その６</title><link>http://blogs.wankuma.com/kazuki/archive/2009/07/03/177013.aspx</link><pubDate>Fri, 03 Jul 2009 12:52:00 GMT</pubDate><guid>http://blogs.wankuma.com/kazuki/archive/2009/07/03/177013.aspx</guid><wfw:comment>http://blogs.wankuma.com/kazuki/comments/177013.aspx</wfw:comment><comments>http://blogs.wankuma.com/kazuki/archive/2009/07/03/177013.aspx#Feedback</comments><slash:comments>1845</slash:comments><wfw:commentRss>http://blogs.wankuma.com/kazuki/comments/commentRss/177013.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/kazuki/services/trackbacks/177013.aspx</trackback:ping><description>&lt;p&gt;&lt;strong&gt;&lt;u&gt;過去の関連記事&lt;/u&gt;&lt;/strong&gt;&lt;br&gt;&lt;a href="http://blogs.wankuma.com/kazuki/archive/2009/06/30/176822.aspx"&gt;[C#][MEF]Managed Extensibility Framework入門 その１&lt;/a&gt;&lt;br&gt;&lt;a href="http://blogs.wankuma.com/kazuki/archive/2009/06/30/176825.aspx"&gt;[C#][MEF]Managed Extensibility Framework入門 その２&lt;/a&gt;&lt;br&gt;&lt;a href="http://blogs.wankuma.com/kazuki/archive/2009/07/01/176869.aspx"&gt;[C#][MEF]Managed Extensibility Framework入門 その３&lt;/a&gt;&lt;br&gt;&lt;a href="http://blogs.wankuma.com/kazuki/archive/2009/07/02/176927.aspx"&gt;[C#][MEF]Managed Extensibility Framework入門 その４&lt;/a&gt;&lt;br&gt;&lt;a href="http://blogs.wankuma.com/kazuki/archive/2009/07/02/176950.aspx"&gt;[C#][MEF]Managed Extensibility Framework入門 その５&lt;/a&gt; &lt;p&gt;前回は、MethodのExportとImportについて試してみました。&lt;br&gt;これまでの5回で、基本的なImportとExportについては出来るようになりました。そして、適切にExport属性をつけるだけで勝手に適切なImport属性がついてるプロパティに設定されるのは素敵だということを感じたと思います。 &lt;p&gt;今回は、同じ条件に合致する複数のExport属性があるときのImportの仕方について見ていこうと思います。 &lt;p&gt;見ていくといっても大して書くことはなくて、これまで&lt;/p&gt; &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:e2d6e34a-7338-45c8-b391-481205f01a8a" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;[Import]
public TPropertyType PropertyName { get; set; }&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;のように普通のプロパティにしていた部分を&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:d4009166-7aa9-4572-980a-8a2b46451d4a" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;[Import]
public List&amp;lt;TPropertyType&amp;gt; PropertyName { get; set; }&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;のようにコレクションにするだけでExportが複数ある場合にコレクションにImportされるようになります。&lt;/p&gt;
&lt;p&gt;ということで簡単に動きを見ていきます。&lt;br&gt;とりあえず、MEFEduというコンソールアプリケーションを作って、System.ComponentModel.Composition.dllを参照に追加して、いつもどおりのコンテナの初期化のコードを書きます。&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:9047bbc3-234d-4bb9-aa8b-7de28abd866b" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;using System.ComponentModel.Composition.Hosting;

namespace MEFEdu
{
    class Program
    {
        static void Main(string[] args)
        {
            // コンテナの初期化
            var catalog = new AssemblyCatalog(
                typeof(Program).Assembly);
            var container = new CompositionContainer(catalog);
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;まず、GreetAppクラスを作成します。Actionのコレクションのプロパティを定義して、Import(“Greet”)という属性を付けています。ついでに、Mainのほうも、コンテナからGreetAppのインスタンスを取得して実行するようにします。&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:765b35ce-18fd-4682-9286-25b939c89fd8" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;using System.ComponentModel.Composition.Hosting;
using System;
using System.ComponentModel.Composition;
using System.Collections.Generic;

namespace MEFEdu
{
    class Program
    {
        static void Main(string[] args)
        {
            // コンテナの初期化
            var catalog = new AssemblyCatalog(
                typeof(Program).Assembly);
            var container = new CompositionContainer(catalog);

            var app = container.GetExportedObject&amp;lt;GreetApp&amp;gt;();
            app.Execute();
        }
    }

    [Export]
    public class GreetApp
    {
        [Import("Greet")]
        public List&amp;lt;Action&amp;gt; GreetActions { get; set; }

        public void Execute()
        {
            // 登録されている挨拶を実行！
            foreach (var action in GreetActions)
            {
                action();
            }
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;GreetAppクラスのGreetActionsに登録するメソッドを定義していきます。Greeterクラスを作成して、そこにメソッドを定義してExport(“Greet”)属性をつけています。&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:83875b2d-687c-4d99-97d6-d672ad987b9a" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;public class Greeter
{
    [Export("Greet")]
    public void HelloWorld()
    {
        Console.WriteLine("Hello world");
    }

    [Export("Greet")]
    public void こんにちは世界()
    {
        Console.WriteLine("こんにちは世界");
    }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これで実行すると、複数のアクションが登録されて、実行されるのがわかります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;実行結果&lt;/strong&gt;&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:9142a12a-3cc5-494e-a428-2b7982f71796" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c"&gt;Hello world
こんにちは世界&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;こういう風にして、アプリケーションを何か作る時に、追加処理したいポイントをDelegateのコレクションのプロパティにImport属性をつけたものにしておくと、簡単に拡張できるようになります！！&lt;/p&gt;
&lt;p&gt;素敵だ。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/kazuki/aggbug/177013.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>kazuki@wankuma.com (かずき)</dc:creator><title>[C#][MEF]Managed Extensibility Framework入門 その５</title><link>http://blogs.wankuma.com/kazuki/archive/2009/07/02/176950.aspx</link><pubDate>Thu, 02 Jul 2009 12:45:00 GMT</pubDate><guid>http://blogs.wankuma.com/kazuki/archive/2009/07/02/176950.aspx</guid><wfw:comment>http://blogs.wankuma.com/kazuki/comments/176950.aspx</wfw:comment><comments>http://blogs.wankuma.com/kazuki/archive/2009/07/02/176950.aspx#Feedback</comments><slash:comments>88</slash:comments><wfw:commentRss>http://blogs.wankuma.com/kazuki/comments/commentRss/176950.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/kazuki/services/trackbacks/176950.aspx</trackback:ping><description>&lt;p&gt;&lt;strong&gt;&lt;u&gt;過去の関連記事&lt;/u&gt;&lt;/strong&gt;&lt;br&gt;&lt;a href="http://blogs.wankuma.com/kazuki/archive/2009/06/30/176822.aspx"&gt;[C#][MEF]Managed Extensibility Framework入門 その１&lt;/a&gt;&lt;br&gt;&lt;a href="http://blogs.wankuma.com/kazuki/archive/2009/06/30/176825.aspx"&gt;[C#][MEF]Managed Extensibility Framework入門 その２&lt;/a&gt;&lt;br&gt;&lt;a href="http://blogs.wankuma.com/kazuki/archive/2009/07/01/176869.aspx"&gt;[C#][MEF]Managed Extensibility Framework入門 その３&lt;/a&gt;&lt;br&gt;&lt;a href="http://blogs.wankuma.com/kazuki/archive/2009/07/02/176927.aspx"&gt;[C#][MEF]Managed Extensibility Framework入門 その４&lt;/a&gt;  &lt;p&gt;前回は、プロパティをExportして、それをImportすることをやりました。MEFでは、そのほかに、メソッドをExportすることが出来ます。&lt;br&gt;このメソッドのExportは、個人的にほかのDIコンテナでは見たことないと感じてる機能なので割りとお気に入りです。  &lt;p&gt;メソッドにExportをつけると、DelegateとしてImportすることが出来ます。&lt;br&gt;例えば…&lt;br&gt;&lt;/p&gt; &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:6407133f-49f7-481d-bf00-f863e4bec207" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;public void Foo(string value)
{
}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;のようなメソッドにExport属性をつけると&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:1e8f321b-83ae-4be5-93dc-7dc82273c9da" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;public Action&amp;lt;string&amp;gt; Hoge { get; set; }&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;こんなプロパティにImportすることが出来ます。&lt;/p&gt;
&lt;p&gt;特に難しいことはないと思うので、さくっとサンプルを書いてみようと思います。&lt;br&gt;MEFExportMethodという名前で、コンソールアプリケーションを作成してSystem.ComponentModel.Composition.dllを参照に追加します。&lt;/p&gt;
&lt;p&gt;まずは、Importをするほうのプログラムを書いてみようと思います。&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:9cd996f5-6955-458d-bcb9-cdd6cd9ca5bb" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;[Export]
public class FooProcess
{
    [Import("FooProcessPreProcess", AllowDefault=true)]
    public Action&amp;lt;string&amp;gt; PreProcess { get; set; }

    public void Execute()
    {
        if (PreProcess != null)
        {
            // 前処理をしてから主処理を実行する
            PreProcess("FooProcess");
        }
        Console.WriteLine("主処理実行！！");
    }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;PreProcessプロパティにImport属性がついています。FooProcessPreProcessという名前のものをImportするという定義にしました。AllowDefault=trueをつけることで、デフォルト値を許すようにしました。AllowDefaultをつけてないと、無理やりImportしようとして、次に書く予定のMainで例外が発生してしまいます。&lt;/p&gt;
&lt;p&gt;次に、Exportのプログラムではなくて、Mainの流れを先に書いて動きを見てみます。&lt;br&gt;コンテナを作成して、FooProcessのインスタンスを取得してExecuteを呼び出しています。&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:96dd86f8-7cce-4604-9601-e4a70593e2fb" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;class Program
{
    static void Main(string[] args)
    {
        // 自身のアセンブリ内のクラスを自動で登録するコンテナを作成
        var catalog = new AssemblyCatalog(typeof(Program).Assembly);
        var container = new CompositionContainer(catalog);

        // FooProcessを取得して処理実行
        var process = container.GetExportedObject&amp;lt;FooProcess&amp;gt;();
        process.Execute();
    }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これを実行すると&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:ce147018-2fae-4d03-9be9-4745d5c4350a" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c"&gt;主処理実行！！&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;と表示されます。とりあえず何も不思議なことはないはず！&lt;/p&gt;
&lt;p&gt;次にメソッドをExportするクラスを書いてみようと思います。&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:fcda5209-a0d7-47c2-a7c0-49db81f7008f" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;public class CustomPreProcess
{
    [Export("FooProcessPreProcess")]
    public void PrintMessage(string message)
    {
        Console.WriteLine(message);
    }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Action&amp;lt;string&amp;gt;型に入れれるように戻り値がvoidで、引数がstring１つのメソッドを定義しています。これにExport属性をつけて、Import側で指定したFooProcessPreProcessという文字列を指定します。&lt;/p&gt;
&lt;p&gt;このクラスを追加して実行すると・・・&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:57660e35-f0a0-44ae-8b44-76e8c8965aa9" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c"&gt;FooProcess
主処理実行！！&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;FooProcessが表示されているのがわかると思います。&lt;br&gt;こうすることで、任意の処理を差し込むポイントを簡単に作りこむことが出来ます。&lt;/p&gt;
&lt;p&gt;個人的にこれはお気に入り！&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/kazuki/aggbug/176950.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>kazuki@wankuma.com (かずき)</dc:creator><title>[C#][MEF]Managed Extensibility Framework入門 その４</title><link>http://blogs.wankuma.com/kazuki/archive/2009/07/02/176927.aspx</link><pubDate>Thu, 02 Jul 2009 00:22:00 GMT</pubDate><guid>http://blogs.wankuma.com/kazuki/archive/2009/07/02/176927.aspx</guid><wfw:comment>http://blogs.wankuma.com/kazuki/comments/176927.aspx</wfw:comment><comments>http://blogs.wankuma.com/kazuki/archive/2009/07/02/176927.aspx#Feedback</comments><slash:comments>53</slash:comments><wfw:commentRss>http://blogs.wankuma.com/kazuki/comments/commentRss/176927.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/kazuki/services/trackbacks/176927.aspx</trackback:ping><description>&lt;p&gt;&lt;a href="http://blogs.wankuma.com/kazuki/archive/2009/06/30/176822.aspx"&gt;[C#][MEF]Managed Extensibility Framework入門 その１&lt;/a&gt;&lt;br&gt;&lt;a href="http://blogs.wankuma.com/kazuki/archive/2009/06/30/176825.aspx"&gt;[C#][MEF]Managed Extensibility Framework入門 その２&lt;/a&gt;&lt;br&gt;&lt;a href="http://blogs.wankuma.com/kazuki/archive/2009/07/01/176869.aspx"&gt;[C#][MEF]Managed Extensibility Framework入門 その３&lt;/a&gt; &lt;p&gt;今回は、ExportAttributeをプロパティにつけたときの動作を見てみようと思います。&lt;br&gt;今までのExportは、一般的なDIコンテナにありがちな感じで、クラスにつけて他のクラスから使えるようにしていました。 &lt;p&gt;このExport属性は、実はクラスだけではなく、プロパティにつけることもできます。こうすることで、プロパティの戻り値をImportのついているプロパティに設定することが出来ます。&lt;/p&gt; &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:65f83d8b-563f-46b5-9ea1-daf2455259f8" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;using System;
using System.ComponentModel.Composition;

namespace MEFExportEdu
{
    // メッセージを提供する人
    public class MessageProvider
    {
        // Messageという名前でExport
        [Export("Message")]
        public string GreetMessage
        {
            get
            {
                return "Hello world";
            }
        }
    }

    [Export]
    public class Greeter
    {
        // MessageをImport
        [Import("Message")]
        public string Message { get; set; }

        public void Greet()
        {
            // 結果としてHello worldが表示されます
            Console.WriteLine(Message);
        }
    }

}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;そして、確認用のMainを作ります。&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:d0fa9f80-0b9f-400d-87bc-5d35ca8b04ba" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;using System.ComponentModel.Composition.Hosting;

namespace MEFExportEdu
{
    class Program
    {
        static void Main(string[] args)
        {
            var catalog = new AssemblyCatalog(typeof(Program).Assembly);
            var container = new CompositionContainer(catalog);

            // 実行！
            var g = container.GetExportedObject&amp;lt;Greeter&amp;gt;();
            g.Greet();
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;実行するとHello worldが表示されます。&lt;br&gt;&lt;a href="http://kazuki.wankuma.com/images/2009/CMEFManagedExtensibilityFramework_535/image.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://kazuki.wankuma.com/images/2009/CMEFManagedExtensibilityFramework_535/image_thumb.png" width="175" height="88"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;この例では、とても無駄なような気がしますが、構成ファイルから読み込んだ文字列を、属性を指定するだけでさくっと取得できるようなことも出来そう。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/kazuki/aggbug/176927.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>kazuki@wankuma.com (かずき)</dc:creator><title>[C#][MEF]Managed Extensibility Framework入門 その３</title><link>http://blogs.wankuma.com/kazuki/archive/2009/07/01/176869.aspx</link><pubDate>Wed, 01 Jul 2009 13:01:00 GMT</pubDate><guid>http://blogs.wankuma.com/kazuki/archive/2009/07/01/176869.aspx</guid><wfw:comment>http://blogs.wankuma.com/kazuki/comments/176869.aspx</wfw:comment><comments>http://blogs.wankuma.com/kazuki/archive/2009/07/01/176869.aspx#Feedback</comments><slash:comments>53</slash:comments><wfw:commentRss>http://blogs.wankuma.com/kazuki/comments/commentRss/176869.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/kazuki/services/trackbacks/176869.aspx</trackback:ping><description>&lt;p&gt;&lt;a href="http://blogs.wankuma.com/kazuki/archive/2009/06/30/176822.aspx"&gt;[C#][MEF]Managed Extensibility Framework入門 その１&lt;/a&gt;&lt;br&gt;&lt;a href="http://blogs.wankuma.com/kazuki/archive/2009/06/30/176825.aspx"&gt;[C#][MEF]Managed Extensibility Framework入門 その２&lt;/a&gt;&lt;/p&gt; &lt;p&gt;その２で簡単なHello worldを作りました。&lt;br&gt;その３では、このHello worldをちょっと改良して、めんどくさかったクラスのインスタンスをコンテナに登録する部分と、DIコンテナチックに実装との間に一枚インターフェースを挟むようにしてみようと思います。&lt;/p&gt; &lt;p&gt;適当にコンソールアプリケーションを作成して、System.ComponentModel.Composition.dllを参照に追加します。&lt;/p&gt; &lt;p&gt;まず最初に、クラスのインスタンスを登録する部分を改善しようと思います。コンテナがどういう風にクラスのインスタンスを登録していくかを指定するものとして、～Catalogというものがあります。&lt;/p&gt; &lt;p&gt;その中に、System.ComponentModel.Composition.Hosting.AssemblyCatalogというものがあります。これは、指定したアセンブリの中にあるクラス群を自動で登録してくれるかわいい奴です。&lt;/p&gt; &lt;p&gt;ということでMainを、それをつかってコンテナを作成するように書きます。&lt;/p&gt; &lt;p&gt; &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:d74bad4e-fa83-4a1a-80e2-052a0397ed52" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;using System.ComponentModel.Composition.Hosting;

namespace MEFSample2
{
    class Program
    {
        static void Main(string[] args)
        {
            // アセンブリからクラス登録してね
            var catalog = new AssemblyCatalog(typeof(Program).Assembly);
            // catalogを使用してコンテナを初期化
            var container = new CompositionContainer(catalog);
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;次に、GreeterとGreeterApp(前のエントリではApplicationって書いてたけどうつのがめんどくさくなったので短いAppにしました）を作成します。&lt;br&gt;各々、IGreeterとIGreetAppインターフェースと、それを実装するGreeterImplとGreetAppImplクラスがあります。&lt;/p&gt;
&lt;p&gt;中身は対して変わりませんが、Export属性とかは、実装クラスのほうにつけて、Export属性の引数にインターフェースの型を指定します。&lt;br&gt;これでコンテナにIGreeterのインスタンス下さいと、問い合わせるとGreeterImplのインスタンスをくれるようになります。&lt;/p&gt;
&lt;p&gt;IGreeterインターフェースとGreeterImplクラス&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:79b07f74-c236-430b-b2f4-a777aba2b10d" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;using System.ComponentModel.Composition;

namespace MEFSample2
{
    // 挨拶をする人が実装すべきインターフェース
    public interface IGreeter
    {
        string Greet();
    }

    // IGreeterの実装　IGreeterインターフェースをキーにしてExportする
    [Export(typeof(IGreeter))]
    public class GreeterImpl : IGreeter
    {
        // 単純にHello worldを返す
        public string Greet()
        {
            return "Hello world";
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;IGreetAppインターフェースとGreetAppImplクラス&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:58e977a9-e0c5-46d6-a285-67308fc36861" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;using System;
using System.ComponentModel.Composition;

namespace MEFSample2
{
    // 挨拶アプリケーションの実装すべきインターフェース
    public interface IGreetApp
    {
        void Run();
    }

    // IGreetAppの実装 IGreetAppをキーにしてExportする
    [Export(typeof(IGreetApp))]
    public class GreetAppImpl : IGreetApp
    {
        // IGreeterをImportする
        [Import]
        public IGreeter Greeter { get; set; }

        public void Run()
        {
            // ちゃんとGreeterにインスタンスが設定されてれば挨拶が表示されるはず
            Console.WriteLine(this.Greeter.Greet());
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;何処にExportとImportがついてるかがポイントです。&lt;br&gt;さて、最後に、Mainを実装します。コンテナからIGreetAppのインスタンスを取得してRunメソッドを呼び出します。&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:f3ea921d-fa66-4d41-bb5d-f89faa4408b0" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;using System.ComponentModel.Composition.Hosting;

namespace MEFSample2
{
    class Program
    {
        static void Main(string[] args)
        {
            // アセンブリからクラス登録してね
            var catalog = new AssemblyCatalog(typeof(Program).Assembly);
            // catalogを使用してコンテナを初期化
            var container = new CompositionContainer(catalog);

            // 実行！
            var app = container.GetExportedObject&amp;lt;IGreetApp&amp;gt;();
            app.Run();
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;だいぶスッキリしました。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/kazuki/aggbug/176869.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>kazuki@wankuma.com (かずき)</dc:creator><title>[C#][MEF]Managed Extensibility Framework入門 その２</title><link>http://blogs.wankuma.com/kazuki/archive/2009/06/30/176825.aspx</link><pubDate>Tue, 30 Jun 2009 23:05:00 GMT</pubDate><guid>http://blogs.wankuma.com/kazuki/archive/2009/06/30/176825.aspx</guid><wfw:comment>http://blogs.wankuma.com/kazuki/comments/176825.aspx</wfw:comment><comments>http://blogs.wankuma.com/kazuki/archive/2009/06/30/176825.aspx#Feedback</comments><slash:comments>38</slash:comments><wfw:commentRss>http://blogs.wankuma.com/kazuki/comments/commentRss/176825.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/kazuki/services/trackbacks/176825.aspx</trackback:ping><description>&lt;p&gt;&lt;a href="http://blogs.wankuma.com/kazuki/archive/2009/06/30/176822.aspx"&gt;[C#][MEF]Managed Extensibility Framework入門 その１&lt;/a&gt;&lt;/p&gt; &lt;p&gt;ということで、MEF Preview 5を試してみます。&lt;br&gt;プログラムを始めるときは、何事もHello worldからです！！ということで、MEFでも慣例に沿ってHello worldを作っていこうと思います。&lt;/p&gt; &lt;h1&gt;プロジェクトの作成～下準備&lt;/h1&gt; &lt;p&gt;ということで、早速コンソールアプリケーションを「MEFHelloWorldApp」という名前で新規作成します。MEF Preview 5を解凍したフォルダの下のbinにあるSystem.ComponentModel.Composition.dllを参照に追加します。&lt;/p&gt; &lt;p&gt;プロジェクトを作成したら、最初に、MEFのコンテナの初期化を行います。&lt;br&gt;とりあえずソースの上にusing(VBならImports)に&lt;/p&gt; &lt;ol&gt; &lt;li&gt;System.ComponentModel.Composition&lt;/li&gt; &lt;li&gt;System.ComponentModel.Composition.Hosting&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;の２つを追加します。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;C#&lt;br&gt;&lt;/strong&gt; &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:b1282285-37d9-421c-9751-2f46d77580d7" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;

namespace MEFHelloWorldApp
{
    class Program
    {
        static void Main(string[] args)
        {
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;VB&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:f1aa9133-e2ea-4a7f-a593-58e24d8fe9c8" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="vb"&gt;Imports System.ComponentModel.Composition
Imports System.ComponentModel.Composition.Hosting

Module Module1

    Sub Main()

    End Sub

End Module
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;そしてMainにコンテナの初期化コードを書いていきます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:a41c3fbf-ed01-4736-9f65-ba63456a0519" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;// コンテナのインスタンスを生成
var container = new CompositionContainer();
// これにコンテナに登録するクラスを指定する
var batch = new CompositionBatch();
// ここでコンテナに登録するクラスを指定する

container.Compose(batch);

// 好きな処理を書く&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;VB&lt;/strong&gt;&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:af7ebc2a-9d57-4b44-982b-d8cba7fe5a4c" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="vb"&gt;' コンテナのインスタンスを生成
Dim container As New CompositionContainer
' これにコンテナに登録するクラスを指定する
Dim batch As New CompositionBatch
' ここでコンテナに登録するクラスを指定する

container.Compose(batch)

' 好きな処理を書く&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これで下準備完了です。&lt;/p&gt;
&lt;h1&gt;Hello worldの作成&lt;/h1&gt;
&lt;p&gt;ここまでは、どのプログラムでも共通する処理です。ここからついにHello worldを作りこんでいきます。&lt;br&gt;作るクラスとしては、Hello worldという文字列を返すGreeterと、それを標準出力へ印字するGreetApplicationの2つのクラスを作ります。これは、説明もいらない程簡単なクラスなのでさくっとコードを載せます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:35f33a5a-ba5f-4e14-a195-c930c27fdc18" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;using System;

namespace MEFHelloWorldApp
{
    public class Greeter
    {
        public string Greet()
        {
            return "Hello world";
        }
    }

    public class GreetApplication
    {
        public Greeter Greeter { get; set; }

        public void Run()
        {
            Console.WriteLine(this.Greeter.Greet());
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;VB&lt;/strong&gt;&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:988aaf7c-4c02-410d-9b39-58a430d3e905" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="vb"&gt;Public Class Greeter
    Public Function Greet() As String
        Return "Hello world"
    End Function
End Class

Public Class GreetApplication
    Private _greeter As Greeter
    Public Property Greeter() As Greeter
        Get
            Return _greeter
        End Get
        Set(ByVal value As Greeter)
            _greeter = value
        End Set
    End Property

    Public Sub Run()
        Console.WriteLine(Me.Greeter.Greet())
    End Sub
End Class
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ここからMEF固有のことをやります。&lt;br&gt;まず、今回のアプリケーションの形は、GreetApplicationが、Greeterを使うという形になります。そのため、GreetApplicationではGreeterクラスを取得できないといけません。逆にGreeterクラスは、他のクラスに自分を使ってもらえないといけません。&lt;/p&gt;
&lt;p&gt;そういうのを表すために属性を追加します。追加する属性は２つで&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;System.ComponentModel.Composition.ExportAttribute&lt;br&gt;自分を外部の人が使えるようにする。&lt;/li&gt;
&lt;li&gt;System.ComponentModel.Composition.ImportAttribute&lt;br&gt;外部の人を取り込む。&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;です。&lt;/p&gt;
&lt;p&gt;ということで、今回はGreeterクラスにExport属性をつけて、GreetApplicationのGreeterプロパティにImport属性をつけます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:72aa0abd-8a19-4aa8-9a4c-7fbaa21abc5b" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;using System;
using System.ComponentModel.Composition;

namespace MEFHelloWorldApp
{
    [Export]
    public class Greeter
    {
        public string Greet()
        {
            return "Hello world";
        }
    }

    public class GreetApplication
    {
        [Import]
        public Greeter Greeter { get; set; }

        public void Run()
        {
            Console.WriteLine(this.Greeter.Greet());
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;VB&lt;/strong&gt;&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:5991a529-5c71-468f-b0a2-85b5d264999a" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="vb"&gt;Imports System.ComponentModel.Composition

&amp;lt;Export()&amp;gt; _
Public Class Greeter
    Public Function Greet() As String
        Return "Hello world"
    End Function
End Class

Public Class GreetApplication
    Private _greeter As Greeter

    &amp;lt;Import()&amp;gt; _
    Public Property Greeter() As Greeter
        Get
            Return _greeter
        End Get
        Set(ByVal value As Greeter)
            _greeter = value
        End Set
    End Property

    Public Sub Run()
        Console.WriteLine(Me.Greeter.Greet())
    End Sub
End Class
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h1&gt;コンテナにクラスを登録して使う&lt;/h1&gt;
&lt;p&gt;粒がそろったので、MEFのコンテナに登録して使ってみようと思います。&lt;br&gt;CompositionBatchのAddPart(object)メソッドを使ってインスタンスを登録します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:9ba3019f-684f-46cb-b882-67de711104cc" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;

namespace MEFHelloWorldApp
{
    class Program
    {
        static void Main(string[] args)
        {
            // コンテナのインスタンスを生成
            var container = new CompositionContainer();
            // これにコンテナに登録するクラスを指定する
            var batch = new CompositionBatch();
            // ここでコンテナに登録するクラスを指定する

            // GreeterとGreetApplicationを追加する
            batch.AddPart(new Greeter());
            var app = new GreetApplication();
            batch.AddPart(app);

            container.Compose(batch);

            // 好きな処理を書く
            app.Run(); // Hello world!!
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;VB&lt;/strong&gt;&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:9985eba1-d9fb-435c-ba35-aa34756652b2" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="vb"&gt;Imports System.ComponentModel.Composition
Imports System.ComponentModel.Composition.Hosting

Module Module1

    Sub Main()
        ' コンテナのインスタンスを生成
        Dim container As New CompositionContainer
        ' これにコンテナに登録するクラスを指定する
        Dim batch As New CompositionBatch
        ' ここでコンテナに登録するクラスを指定する

        ' GreeterとGreetApplicationを追加する
        batch.AddPart(New Greeter())
        Dim app As New GreetApplication
        batch.AddPart(app)

        container.Compose(batch)

        ' 好きな処理を書く
        app.Run()
    End Sub

End Module
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;これで、コンテナにGreeterクラスのインスタンスとGreetApplicationクラスのインスタンスを登録してGreetApplicationのRunを実行してます。恐らくcontainer.Compose(batch)の時点で、Export属性やImport属性を見て適切にコンテナが依存性を解決してくれてると思われます。&lt;/p&gt;
&lt;p&gt;証拠にこのアプリケーションを実行すると、GreetApplicationのGreeterプロパティに値を設定してるコードが無いにもかかわらず、Hello worldが表示されます。&lt;br&gt;&lt;a href="http://kazuki.wankuma.com/images/2009/CMEFManagedExtensibilityFramework_13D67/image.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://kazuki.wankuma.com/images/2009/CMEFManagedExtensibilityFramework_13D67/image_thumb.png" width="234" height="81"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;ということでMEFのHello worldでした。&lt;br&gt;今回の方法だと、コンテナに登録するインスタンスを全て事前に作っておかないといけないのか！？って感じですけど、ちゃんとフル機能使えば、アセンブリにある属性のついたクラス全部を対象にしたり、フォルダに入ってるアセンブリから読み込んだり夢広がる設計になっています。&lt;/p&gt;
&lt;p&gt;ということで、今日はここまで！続きもやるかも・・・？（C#とVB両方用意するの疲れた）&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/kazuki/aggbug/176825.aspx" width = "1" height = "1" /&gt;</description></item></channel></rss>