【MEF】CodePlexを改めて眺めてみた。

  • 2010.05.20 Thursday
  • 00:59
JUGEMテーマ:コンピュータ
 
CodePlex
http://mef.codeplex.com/

ヴァージョンの違いはありますがCodePlexのMEFのページにはMEFの実装とサンプルコードがダウンロードできます。

WPFの使用例としてXFileExplorerというのがありWinFormにMefStudio(VisualStudioのUIを再現したアプリ)などがあります。動かすだけでも結構たのしいのでお勧めです(笑)

【MEF】N層によるパーツの管理

  • 2010.05.19 Wednesday
  • 22:24
JUGEMテーマ:コンピュータ

Source and Project
 
ちょっとしたMEFアプリケーションを構築するためオンメモリのデータベースを用意し、そこにアクセスするためのデータアクセス層とそのデータを使用して上位命令を実行するロジック層を構築してみました。中身の実装やデータモデルが微妙な位置に配置していたりと、中途半端感は否めませんが、ちょっとしたアプリケーションを構築するだけなら、これでも結構楽しめるかなーって思います。

IDataAccess.dll

using DataBase;

namespace IDataAccess
{
    public interface IGeEmplyeeDataSet
    {
        /// <summary>
        /// 全従業員を取得する。
        /// </summary>
        /// <returns></returns>
        EmplyeeDataSet SelectAll();
    }
}

DataAccessImpl.dll

using System.ComponentModel.Composition;
using DataBase;
using DataBase.EmplyeeDataSetTableAdapters;
using IDataAccess;

namespace DataAccessImpl
{
    [Export(typeof(IGeEmplyeeDataSet))]
    public class GetEmplyeeDataSetImpl : IGeEmplyeeDataSet
    {
        /// <summary>
        /// 全従業員を取得する。
        /// </summary>
        /// <returns></returns>
        public EmplyeeDataSet SelectAll()
        {
            var emplyeeDataSet = new EmplyeeDataSet();
            var adapter = new EmployeeTableAdapter();
            adapter.Fill(emplyeeDataSet.Employee);
            emplyeeDataSet.AcceptChanges();
            return emplyeeDataSet;
        }
    }
}


ILogic.dll

using DataBase;

namespace ILogic
{
    public interface IGetEmplyees
    {
        EmplyeeDataSet Execute();
    }
}

LogicImpl.dll

using System.ComponentModel.Composition;
using DataBase;
using IDataAccess;
using ILogic;

namespace LogicImpl
{
    [Export(typeof(IGetEmplyees))]
    public class GetEmplyeesImpl : IGetEmplyees
    {
        [Import(typeof(IGeEmplyeeDataSet))]
        public IGeEmplyeeDataSet GeEmplyeeDataSet { private get; set; }

        public EmplyeeDataSet Execute()
        {
            return GeEmplyeeDataSet.SelectAll();
        }
    }
}



EmplyeeDataSet クラスの定義位置がおかしい・・・うん。

Source and Project

------
追記

[PartCreationPolicy(CreationPolicy.Shared)]
をつけるの忘れてた・・・。

【MEF】Lazy<T>クラスの実装を見る。

  • 2010.05.17 Monday
  • 20:21
JUGEMテーマ:コンピュータ

 
Managed Extensibility Framework
http://mef.codeplex.com/

ご存知のとおりMEFはCodePlexで開発が進められていたため、ヴァージョンの違いはありますが、ソースコードが公開されています。ちょっと気になるところがあれば、ソースコードをのぞくことができます。

たとえばLazy<T>クラスもそのひとつです。

Lazy<T>クラスは

Mef_Preview_9¥src¥ComponentModel¥System¥Lazy.cs

にあります。実装をみると非常にシンプルな実装になっていることがわかります。さらにシンプルにするためにスレッドセーフを実装せずにMyLazy<T>クラスを実装してみました。

using System;

namespace Art55.CommponentModel
{
    public class MyLazy<T>
    {
        public MyLazy()
            : this (Activator.CreateInstance<T>)
        {}

        public MyLazy(Func<T> valueFactory)
        {
            if (valueFactory == null)
            {
                throw new ArgumentNullException("valueFactory");
            }

            _valueFactory = valueFactory;
        }

        public T Value
        {
            get
            {
                if (!IsValueCreated)
                {
                    _value = _valueFactory.Invoke();
                    _valueFactory = null;
                    IsValueCreated = true;
                }
                return _value;
            }
        }

        public bool IsValueCreated { get; private set; }

        private T _value;
        private Func<T> _valueFactory;
    }
}

昔、初めてプロパティにアクセスしたときに、インスタンスを作成するコードを書きたくて、いろいろ考えたなーって昔のことを思い出しました。

【MEF】ImportingConstructorを試す。

  • 2010.05.16 Sunday
  • 07:52
JUGEMテーマ:コンピュータ


using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;

namespace ConsoleApplication3
{
    class Program
    {
        static void Main()
        {
            var catalog = new AssemblyCatalog(typeof (Program).Assembly);
            var container = new CompositionContainer(catalog);
            container.GetExportedValue<A>().Say();
        }
    }

    [Export]
    public class A
    {
        public A()
        {
        }

        [ImportingConstructor]
        public A(B b)
        {
            _b = b;
        }

        private B _b;
        public void Say()
        {
            _b.Say();
        }
    }

    [Export(typeof(B))]
    public class B
    {
        public void Say()
        {
            Console.WriteLine("B Say");
        }
    }
}


複数のコンストラクタがあり、属性付きプログラミング モデルで任意のコンストラクタを選びたい場合は「[ImportingConstructor]」を指定することで実現できます。循環参照するパート同士を回避できなかったり、コンストラクタのパラーメータへのImportの記述がちょっとアレな感じなので、大抵セッターに対してImportするのが「一般的」なのではないかと思います。

【MEF】メソッドにExport属性を指定する。

  • 2010.05.15 Saturday
  • 17:43
JUGEMテーマ:コンピュータ

http://msdn.microsoft.com/ja-jp/library/ee155691(v=VS.100).aspx

上記のURLの文中に

Export 属性で装飾できるのは、クラス、フィールド、プロパティ、およびメソッドです。
Import 属性で装飾できるのは、フィールド、プロパティ、およびコンストラクター パラメーターです。

とあります。

Export属性はメソッドにも修飾できるのか!?と最初は驚いたのですが、実際にコードを書けばすぐに納得できました。下記が試してみたサンプルコードです。

using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;

namespace ConsoleApplication3
{
    class Program
    {
        static void Main()
        {
            var catalog = new AssemblyCatalog(typeof (Program).Assembly);
            var container = new CompositionContainer(catalog);
            container.GetExportedValue<A>().Say();
        }
    }

    [Export]
    public class A
    {
        [Import]
        public Action Say { get; set; }
    }

    public class B
    {
        [Export(typeof(Action))]
        public void Say()
        {
            Console.WriteLine("B Say");
        }
    }
}

確かにExport属性はメソッドに修飾できて問題ないと理解できます。受け取る側であるImortは当然、デリゲートになりますね。

お試し程度なのでどこまで手堅く書くか悩ましいところなのですが、コントラクトを推論を指定するというケースはAction型の場合はあまり賢くないかなと思います。

書くなら下記のほうがよりベターでしょうかね。

    [Export]
    public class A
    {
        [Import("Say")]
        public Action Say { get; set; }
    }

    public class B
    {
        [Export("Say", typeof(Action))]
        public void Say()
        {
            Console.WriteLine("B Say");
        }
    }

この手の話をするなら、もっと厳密に、手堅く・・・と、ああ悩ましい(笑)

【MEF】コントラクト名でImportとExportを試す。

  • 2010.05.15 Saturday
  • 10:53
JUGEMテーマ:コンピュータ

 
明示的にコントラクト名を指定するサンプルコード(機能を試す程度のものです)を書いてみました。

using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;

namespace ConsoleApplication3
{
    class Program
    {
        static void Main()
        {
            var catalog = new AssemblyCatalog(typeof (Program).Assembly);
            var container = new CompositionContainer(catalog);
            A a = container.GetExportedValue<A>();
            Console.WriteLine(a.Now.ToString());
        }
    }

    [Export]
    public class A
    {
        [Import("Now")]
        public DateTime Now { get; set; }
    }

    public class B
    {
        [Export("Now")]
        public DateTime Now = DateTime.Now;

        [Export("Yesterday")]
        public DateTime Yesterday= DateTime.Now.AddDays(-1);
    }
}


インポートとエックスポートの表現方法として「属性付きプログラミング モデル」を使用しMEFアプリケーションを作ってみました。コントラクト名を明示的に指定することでエックスポートを、AオブジェクトのNowプロパティが要求するインポートの値を渡せます。

Export属性で装飾可能はクラス、フィールド、プロパティ、メソッドとなっており、いろいろできるんだなーってワクワクしちゃいます。たぶん、クラスぐらいにしかつけないと思いますが(笑)

【MEF】Lasy<T>クラスを使用してインポートを遅らせる。

  • 2010.05.13 Thursday
  • 22:41
JUGEMテーマ:コンピュータ

 Lazy<T>クラスの使いどころのひとつがわかりました。

using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;

namespace ConsoleApplication3
{
    class Program
    {
        static void Main()
        {
            var catalog = new AssemblyCatalog(typeof (Program).Assembly);
            var container = new CompositionContainer(catalog);
            container.GetExportedValue<A>().Say();
        }
    }

    [Export(typeof(A))]
    public class A
    {
        [Import]
        public Lazy<B> B { private get; set; }

        public void Say()
        {
            B.Value.Say();
        }
    }

    [Export(typeof(B))]
    public class B
    {
        public void Say()
        {
            Console.WriteLine("B Say");
        }
    }
}



[Import]
public Lazy<B> B { private get; set; }

と書いておくと、B.ValueまたはB.ToString()が呼び出されるまで、Bクラスがインスタン化されることがなくなります。BクラスまたはBクラスが利用するなんらかのクラスに重い処理や大量のインスタンスを一気に作るといった処理を防ぐことができるので、これは意外につかえるかもしれません。

あと、Lazy<T>の場合はTクラスがコントラクト型になってくれるという仕様があるのもポイントですね。

※このコードがあくまでMEFの機能を試用するためのコードでフレームワークとしてMEFを使用す場合は、モジュールの配置などを考慮する必要があります。

【MEF】コンテナ内でパーツ同士を合成してみる。

  • 2010.05.13 Thursday
  • 21:29
JUGEMテーマ:コンピュータ

カタログで指定したパーツ同士がうまいこと構成されるのか試してみました。

using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
namespace ConsoleApplication3
{
    class Program
    {
        static void Main()
        {
            var catalog = new AssemblyCatalog(typeof (Program).Assembly);
            var container = new CompositionContainer(catalog);
            container.GetExportedValue<A>().Say();
        }
    }

    [Export(typeof(A))]
    public class A
    {
        [Import]
        public B B { private get; set; }

        public void Say()
        {
            B.Say();
        }
    }
    [Export(typeof(B))]
    public class B
    {
        public void Say()
        {
            Console.WriteLine("B Say");
        }
    }
}

また何の利点も恩恵もないサンプルコードですが、ちゃんとImportが動作するのをみてちょっぴり感動しました。

【MEF】MEFとUnity Application Block

  • 2010.05.12 Wednesday
  • 23:03
JUGEMテーマ:コンピュータ
 
以前、Unity Application Blockを試す程度に使ってみたことがあったので、Application Blockは.NET Framework 4.0ではサポートされないのかーってちょっと残念な気持ちになったのですが、MEFを使用してみて納得しました。MEFは確かにフレームワークといえる代物でApplication Blockはフレームワークとはちょっといいがたく、もう少し自由度が高いというかツールに近いというべきか、中途半端な感じでした。Application Blockの実装の中身を見るのはとても楽しかったですけどね。ええ。暇を見つけてApplication Blockも眺めてみたいと思います。

Unity Application Block 2.0
http://msdn.microsoft.com/en-us/library/dd203101.aspx

【MEF】DirectoryCatalogを試してみる。

  • 2010.05.12 Wednesday
  • 22:03

Source and Project

前回のMEF関連のカタログの概念がよくわからないと書きましたが、MSDNライブラリを眺めていると、日本語でしっかりと説明が書かれいました。斜め読みしていたため見落としてました。

MSDNによると

  • パート、カタログ、および合成コンテナー

    パートと合成コンテナーは、MEF アプリケーションの基本のビルド ブロックです。パートは、それ自体までの (自身を含む) 値をインポートまたはエクスポートするオブジェクトです。カタログは、特定のソースからのパートのコレクションを提供します。合成コンテナーは、カタログによって提供されるパートを使用して合成 (インポートのエクスポートへの結合) を実行します。

  • インポートとエクスポート

    インポートとエクスポートは、コンポーネントが通信を行う手段です。インポートを使用して、コンポーネントは特定の値またはオブジェクトが必要であることを指定します。エクスポートを使用して、コンポーネントは値が使用可能であることを指定します。各インポートは、コントラクトを通じて、エクスポートの一覧と対応付けされます。

    http://msdn.microsoft.com/ja-jp/library/dd460648(v=VS.100).aspx#conclusion

    とあります。個人的には非常にわかりやすい説明だと思います。また、クラスの説明に関してもじっくり眺めるとカタログの概念がなんとなくわかってきました。しかし、まだ自分の言葉で書き下せるほどは理解していないというのが現状です。

    まあとにもかくにもコードが書きたい人間なので今回はDirectoryCatalogを試してみました。クラス名だけを頼りに直感でコードを書いてみました(笑)

    今回はパーツとなるモジュールを分けています。

    登場するDLLは、インターフェイスを定義しているILogic.dllとその実装モジュールであるLogicImpl.dll、そして、コンテナ経由で得たインスタンスを実行するMEFSample20100512_001.exeです。

    まずはILogic.dllの説明から

    namespace ILogic
    {
        public interface ISay
        {
            void Execute();
        }
    }

    と、インターフェイスを1つ定義しておきます。

    LogicImpl.dllはILogic.dllを参照します。

    using System;
    using System.ComponentModel.Composition;
    using ILogic;

    namespace LogicImpl
    {
        [Export(typeof(ISay))]
        public class SayImpl : ISay
        {
            public void Execute()
            {
                Console.WriteLine("にゃー");
            }
        }
    }

    Executeメソッドが呼び出されると「にゃー」が出力されます。
    今回は属性プログラミングモデルを採用しています。エクスポートのコントラクトに型情報をしています。

    最後にMEFSample20100512_001.exeですが、コンテナを経由して、ISayを実行します。

    using System;
    using System.ComponentModel.Composition.Hosting;
    using System.IO;
    using ILogic;

    namespace MEFSample20100512_001
    {
        class Program
        {
            static void Main()
            {
                var catalog = new AggregateCatalog();
                catalog.Catalogs.Add(new DirectoryCatalog(Path.Combine(Environment.CurrentDirectory, "lib")));
                var container = new CompositionContainer(catalog);
                var say = container.GetExportedValue<ISay>();
                say.Execute();
            }
        }
    }


    catalog.Catalogs.Add(new DirectoryCatalog(Path.Combine(Environment.CurrentDirectory, "lib")));
    var container = new CompositionContainer(catalog);

    実行モジュールの直下のlibディレクトからパーツを探す、コンテナに提供します。


    var say = container.GetExportedValue<ISay>();

    指定した型がコントラクトとなっているパーツを検索しLasyクラス経由でインスタンスを受け取ります。
    そしてExecuteメソッドを実行という形です。

    意外と簡単に実装できたので拍子抜けです。

    Source and Project

  • calendar

    S M T W T F S
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
    << July 2018 >>

    あわせて読みたい

    あわせて読みたいブログパーツ

    selected entries

    categories

    archives

    recent comment

    • 【キーボード】6年前のRealForceを復活させることはできる!?その3
      art55 (05/22)
    • 【キーボード】6年前のRealForceを復活させることはできる!?その3
      分解大好き (05/18)
    • 【.NET Framework 4.5】 IListがIReadOnlyListを継承してない理由。
      art55 (02/04)
    • 【.NET Framework 4.5】 IListがIReadOnlyListを継承してない理由。
      Gen (02/04)
    • 【キーボード】RealForce が壊れて帰ってきた。
      art55 (04/29)
    • 【.NET Framework 4.5】 IListがIReadOnlyListを継承してない理由。
      art55 (02/23)
    • 【.NET Framework 4.5】 IListがIReadOnlyListを継承してない理由。
      かるあ (02/22)
    • 【C#】Dictionaryの実装・データ構造・アルゴリズムを観察する。
      art55 (01/16)
    • 【C#】Dictionaryの実装・データ構造・アルゴリズムを観察する。
      karuakun (01/16)
    • 【NetOffice】【Excel】死なないExcelプロセスをKillする。
      art55 (12/05)

    recent trackback

    recommend

    recommend

    recommend

    C#プログラマのための.NETアプリケーション最適化技法 (Programmer's SELECTION)
    C#プログラマのための.NETアプリケーション最適化技法 (Programmer's SELECTION) (JUGEMレビュー »)
    Sasha Goldshtein,Dima Zurbalev,Ido Flatow,サシャ・ゴルドシュタイン,ディマ・ズルバレフ,イド・フラトー

    recommend

    ろんりと集合
    ろんりと集合 (JUGEMレビュー »)
    中内 伸光
    とてもわかりやすいです。

    recommend

    recommend

    シャノン・ノイマン・ディジタル世界
    シャノン・ノイマン・ディジタル世界 (JUGEMレビュー »)
    市川 忠男
    4章がリレーショナルデータベースな内容になってます。ページ数があまりありませんが、ポイントがものすごく的確にまとまっていて、感動します。

    recommend

    recommend

    東プレ Realforce91UBK-S 静音キーボード 静電容量無接点方式 変荷重 ブラック NG01BS
    東プレ Realforce91UBK-S 静音キーボード 静電容量無接点方式 変荷重 ブラック NG01BS (JUGEMレビュー »)

    テンキーレス、静音のRealForce91UBK-S。スコスコ感がたまらなく気持ちいいです。家と会社で2台持ってます。

    recommend

    recommend

    プログラミング.NET Framework 第4版 (プログラミングシリーズ)
    プログラミング.NET Framework 第4版 (プログラミングシリーズ) (JUGEMレビュー »)
    Jeffrey Richter
    発売予定美 2013年10月10日。.NET Frameworkとお付き合いする人のバイブルですね。

    recommend

    recommend

    キャット・シッターの君に。
    キャット・シッターの君に。 (JUGEMレビュー »)
    喜多嶋 隆
    私のイラストレータデビュー本です。

    recommend

    Essential .NET ― 共通言語ランタイムの本質
    Essential .NET ― 共通言語ランタイムの本質 (JUGEMレビュー »)
    ドン・ボックス,クリス・セルズ,Don Box,Chris Sells,吉松 史彰

    links

    profile

    search this site.

    others

    mobile

    qrcode

    powered

    無料ブログ作成サービス JUGEM