上一篇我們已經獲得了制定類型的實例,但我們還無法對其進行有效的控制。
我們用ExportMetadata屬性可以對具體的某個實例做標記,相當於命名。這麼理解不知道對否。
在IPart項目中添加一個接口IPatMetadata
namespace IPart
{
public interface IPatMetadata
{
string Extension { get; }//以後綴名來區分,特別需要注意,這裡的名稱要和ExportMetadata裡面的一致。
}
}
在導出的地方添加具體的導出元數據ExportMetadata,以txtFileHandler為例
using IPart;
using System;
using System.ComponentModel.Composition;
namespace Parts
{
[Export(typeof(IFileHandler))]//表示此類需要導出,導出的類型為IFileHandler
[ExportMetadata("Extension",".txt")]//添加導出元數據Ext,值為.txt
public class TxtFileHandler : IFileHandler
{
public void Process()
{
Console.WriteLine("處理文本文件");
}
}
}
導出加了元數據,導入、使用的時候就發生了一點小變化。
主函數:
using IPart;
using System;
using System.ComponentModel.Composition.Hosting;
namespace meftest
{
class Program
{
//容器,裝東西用的。具體裝什麼先不管。
private static CompositionContainer container;
static void Main(string[] args)
{
//AssemblyCatalog 目錄的一種,表示在程序集中搜索
var assemblyCatalog = new AssemblyCatalog(typeof(Program).Assembly);//此處這一句實際上沒啥用,因為此程序集下沒有任何我們需要的實例(各種handler)
//在某個目錄下的dll中搜索。
var directoryCatalog = new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory,"*.dll");
var aggregateCatalog = new AggregateCatalog(assemblyCatalog, directoryCatalog);
//創建搜索到的部件,放到容器中。
container = new CompositionContainer(aggregateCatalog);
var exports = container.GetExports<IFileHandler,IPatMetadata>();//獲得所有導出的部件(IFileHandler,並且帶有IPatMetadata類型元數據,並且元數據的名字為Extension的實例)。
foreach (var item in exports)
{
Console.WriteLine(item.Metadata.Extension); //此處已可以獲取元數據
item.Value.Process();//此處已經可以調用IFileHandler.Process()了
}
Console.ReadLine();
}
}
}
運行結果:

在本例中,我們已經可以取得所有的文件Handler和其對應的元數據,這樣我們就可以用linq的形式有針對性的取得某個具體文件的所對應的實例來進行處理了。說的很繞口,不過,等你看到代碼你就會說,太easy了。
下一篇我們將傳入文件名變量,做一個較為完整的文件管理器。
最恨天下文章一大抄,請不要轉載。