文章參考:在MEF中實現延遲加載部件 作者:TianFang
當某一組件並不是立刻需要使用,或者內存開銷很大。影響程序加載的速度。比如當程序啟動的時候。這個時候我們可以使用延遲加載,也就是只有當程序用到的時候才會去加載該部件。我們可以使用Lazy<T>來標記導入的類型。這樣就簡單的實現了延遲加載。
注意如果使用Lazy<T>來標記對象類型的話,需要通該實例的Value屬性調用實例方法 _logger.Value.Log("hello world");
如果是非延遲加載
using System; using System.Collections.Generic; using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting; using System.Linq; namespace 延遲加載 { interface ILogger { void Log(string message); } [Export(typeof(ILogger))] class ConsoleLogger : ILogger { public void Log(string message) { Console.WriteLine("ConsoleLogger " + message); } } [Export(typeof(ILogger))] class DbLogger : ILogger { public void Log(string message) { Console.WriteLine("DbLogger " + message); } } class Host { //非延遲加載 //[ImportMany] //ILogger[] _logger = null; //延遲加載 [ImportMany] Lazy<ILogger>[] _Lazylogger = null; public Host() { var catalog = new AssemblyCatalog(this.GetType().Assembly); var container = new CompositionContainer(catalog); //非延遲加載此時會創建所有對象 container.ComposeParts(this); //非延遲加載 //_logger.FirstOrDefault(i => i is DbLogger).Log("hello world"); //延遲加載,當調用的時候才創建對象, //但是因為這兒有一個遍歷,所以當調用一個對象的時候就會創建所以對象 _Lazylogger.FirstOrDefault(i => i.Value is DbLogger).Value.Log("DbLogger"); } } } View Code
此時可以用ImportMany標記導入,同時用Lazy<T>包裝我們的導入類型。但是此時有個問題,就是當我們如果通過類型遍歷多個對象尋找可用導入時候,會創建所有對象。所以此時我們可以用元數據來判斷是否使我們需要的導入。
通過元數據可以匹配我們需要的導出服務。但是,通過單純的標記 [ExportMetadata("Name", "DbLogger")]很麻煩,而且屬性筆記多的時候代碼也不整潔。對此我們可以封裝一個元數據特性
using System; using System.Collections.Generic; using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting; using System.Linq; namespace 延遲加載 { interface ILogger { void Log(string message); } //通過標記元數據來標記導出服務 [LoggerData("Console Logger")] [Export(typeof(ILogger))] class ConsoleLogger : ILogger { public void Log(string message) { Console.WriteLine("ConsoleLogger " + message); } } //通過標記元數據來標記導出服務 [LoggerData("DbLogger")] [Export(typeof(ILogger))] class DbLogger : ILogger { public void Log(string message) { Console.WriteLine("DbLogger " + message); } } public interface ILoggerData { string Name { get; } } [MetadataAttribute] [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] class LoggerDataAttribute : Attribute, ILoggerData { public string Name { get; private set; } public LoggerDataAttribute(string name) { this.Name = name; } } class Host { //延遲加載 [ImportMany] Lazy<ILogger, ILoggerData>[] _Lazylogger = null; public Host() { var catalog = new AssemblyCatalog(this.GetType().Assembly); var container = new CompositionContainer(catalog); //非延遲加載此時會創建所有對象 container.ComposeParts(this); //延遲加載,當調用的時候才創建對象, //但是因為這兒有一個遍歷,所以當調用一個對象的時候就會創建所以對象 //_Lazylogger.FirstOrDefault(i => i.Value is DbLogger).Value.Log("DbLogger"); _Lazylogger.FirstOrDefault(i => i.Metadata.Name == "DbLogger").Value.Log("DbLogger"); } } }
本文地址:http://www.cnblogs.com/santian/p/4357324.html
博客地址:http://www.cnblogs.com/santian/
轉載請以超鏈接形式標明文章原始出處。