その他

概念

 MEFでサービスのエクスポートやインポート時に識別子を付与する事が出来ます。この識別子を「コントラクト」と言います。コントラクトには以下の種類があります。

  • 名前コントラクト(文字列で識別子を設定)
  • 型コントラクト(型で識別子を設定)

用語

  • 合成コンテナー
    MEF のコア
  • カタログ
    合成コンテナーは、カタログを使用して使用可能なパーツを検出します。
  • パーツ
    属性つけられたクラス、メソッドなどの部品
  • インポート
    Import属性
  • エクスポート
    Export属性
  • コントラクト
    インポート・エクスポート属性の識別子

サンプル

一般的な「Hello,World」サンプル:

static void Main(string[] args) 
{ 
     Console.WriteLine("Hello,World."); 
} 

上記のロジックを MEF でやり直します。ロジックを2つ部分を分けます、一つは文字列を提供する、一つは文字列を処理します。

 文字列を提供する部分では、下記のように「OutPut」メソッドに「Print」識別子で「Export」属性をつけます、ここではエクスポートがあることを示します。

public class StringProvider 
{ 
   [Export("Print")] 
   public string Output 
   { 
       get { return "Hello,World"; } 
   } 
} 

 文字列を処理するする部分では、下記のように、「message」変数に「Print」識別子で「Import」属性をつけます(複数のExportの場合は「ImportMany」を利用します。)、ここでは、「Print」識別子のエクスポートを探して、変数に渡します。

public class Client 
{ 
   [Import("Print")] 
   private string message=null; 
   
   public void print() 
   { 
       Console.WriteLine(this.message); 
   } 
} 

 インポート・エクスポートの識別子が存在しない場合、下記のような例外が発生します。

ハンドルされていない例外: System.ComponentModel.Composition.ChangeRejectedExcept
ion: コンポジションは変更されませんでした。次のエラーのために、変更は拒否されま
した: コンポジションで、コンポジション エラーが 1 件発生しました。根本原因は次の
とおりです。 詳細については、CompositionException.Errors プロパティを確認してく
ださい。
1) 制約 '((exportDefinition.ContractName == "System.String") AndAlso (exportDefi
nition.Metadata.ContainsKey("ExportTypeIdentity") AndAlso "System.String".Equals
(exportDefinition.Metadata.get_Item("ExportTypeIdentity"))))' に一致する有効なエ
クスポートが見つかりませんでした。無効なエクスポートが拒否されている可能性があり
ます。
結果: パーツ 'ConsoleApplication1.Client' のインポート 'ConsoleApplication1.Clie
nt.message (ContractName="System.String")' を設定できません。
要素: ConsoleApplication1.Client.message (ContractName="System.String") -->  Con
soleApplication1.Client

以上で、エクスポートとインポートの口を完成しました。次は「コンテナー」によって動作させます。

using System; 
using System.ComponentModel.Composition; 
using System.ComponentModel.Composition.Hosting; 
namespace cc.ejb.blogs.example 
{ 
   class Program 
   { 
       static void Main(string[] args) 
       { 
           CompositionContainer container = new CompositionContainer(); 
           CompositionBatch batch = new CompositionBatch(); 
           Client client = new Client(); 
           batch.AddPart(new StringProvider()); 
           batch.AddPart(client); 
           container.Compose(batch); 
           client.print(); 
       } 
   } 
} 

 ここでは合成コンテナー CompositionContainer のインスタンスを作成し、必要なパーツをコンテナーに追加します。MEFは AssemblyCatalog、DirectoryCatalog、また二つの組み合わせ方式で、パーツを抽出できます。

DirectoryCatalog は、指定されたディレクトリの中の DLL ファイルから属性付きパーツは抽出します。 AssemblyCatalogは、指定されたアセンブリの中から、属性付きパーツは抽出します。

 AssemblyCatalog方法

CompositionContainer container = new CompositionContainer(new AssemblyCatalog(typeof(Client).Assembly));
Client client = new Client(); 
container.SatisfyImportsOnce(client); 
client.print(); 

 DirectoryCatalog方法
 DirectoryCatalog方式では、デフォルトの「ISearchPattern」は「*.dll」です、場合によって「*.exe」を設定する必要があります。

CompositionContainer container = new CompositionContainer(
			new DirectoryCatalog(
					System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
					,"*.exe"
					)
		);
Client client = new Client(); 
container.SatisfyImportsOnce(client); 
client.print(); 

 両方:

AggregateCatalog catalog = new AggregateCatalog(); 
catalog.Catalogs.Add(new AssemblyCatalog(typeof(Client).Assembly)); 
CompositionContainer _container = new CompositionContainer(catalog); 


中古車買取実績No.1ガリバー

コメント:



(画像の文字列を入力して下さい)

トップ   編集 凍結 差分 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2019/12/02 (月) 12:33:11 (1627d)

PCpዾyǗlgĂ܂}WŔ܂z 萔O~ył񂫁z Yahoo yV NTT-X Store

z[y[W ̃NWbgJ[h COiq ӂ邳Ɣ[ COsیI COze