過去の関連記事
[C#][MEF]Managed Extensibility Framework入門 その1
[C#][MEF]Managed Extensibility Framework入門 その2
[C#][MEF]Managed Extensibility Framework入門 その3
[C#][MEF]Managed Extensibility Framework入門 その4
[C#][MEF]Managed Extensibility Framework入門 その5
[C#][MEF]Managed Extensibility Framework入門 その6
MEF入門も、既に7回目になりました。
あと何個か書くネタがありますが、今回は今までと趣向を変えてCatalogについてちょっと試してみようと思います。
同一アセンブリしか駄目なの?
いきなり変なタイトルをつけましたが、今までのサンプルは、AssemblyCatalogというクラスを使ってコンテナを作成していました。このAssemblyCatalogは、引数で指定したアセンブリの中からExport属性やImport属性のついたものを自動的に収集してくれるいい奴です。
ただ、これだと1つのアセンブリからしかクラスを取得できません。
後は、第二回で使ったCompositionBatchを使って1つ1つ登録しないといけないみたいに感じてしまいますが、そんなことはありません。
ちゃんと、他にも~Catalogクラスがあります。
Catalog系クラス達
Catalog系というのも今勝手につけた言い方ですが、~Catalogという名前のクラスを4つ紹介したいと思います。
- System.ComponentModel.Composition.Hosting.TypeCatalog
名前からわかるとおり、指定された型を対象にするカタログクラスです。 - System.ComponentModel.Composition.Hosting.AssemblyCatalog
今までお世話になってきた、指定したアセンブリ内のクラスを対象にするカタログクラスです。 - System.ComponentModel.Composition.Hosting.DirectoryCatalog
こいつが今回の大本命です。
指定したディレクトリ内にあるアセンブリを勝手に読み込んでくれます。うわさによると、実行中に追加されたDLLも認識するとか・・・。 - System.ComponentModel.Composition.Hosting.AggregateCatalog
複数のCatalogを一まとめにする縁の下の力持ち
TypeCatalog
TypeCatalogは、コンストラクタで渡したTypeを対象にするクラスです。何かフレームワークとかで決まった型を登録したいとかいうときに使いそう?
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<GreetApp>();
app.Execute();
}
}
}
このコードでHello worldが表示されます。
AssemblyCatalog
これまでのサンプルの通りなので省略
AggregateCatalog
AggregateCatalogは、複数のCatalogを1まとめにするために使います。
例えば、AssemblyCatalogとTypeCatalogを1まとめにして、コンテナに渡す場合は下のようになります。
// 型A, B, Cを登録するよ
var typeCatalog = new TypeCatalog(
typeof(A), typeof(B), typeof(C));
// 型Programのあるアセンブリ内のクラスを登録するよ
var assmCatalog = new AssemblyCatalog(
typeof(Program).Assembly);
// typeCatalogとassmCatalogを1まとめに
var aggCatalog = new AggregateCatalog(
typeCatalog, assmCatalog);
// typeCatalogとassmCatalogにある両方の型が登録されたコンテナの完成
var container = new CompositionContainer(aggCatalog);
CompositionContainerが、Catalogを1つしか受け取らないので、複数のCatalogを使いたいときは、AggregateCatalogで事前に1まとめにしておく必要があるようです。
DirectoryCatalogについては、また次回で(時間切れ)!