文章參考:在MEF中實現延遲加載部件 作者:TianFang

using System;using System.Collections.Generic;using System.ComponentModel.Composition;using System.ComponentModel.Composition.Hosting;namespace 延遲加載{ interface ILogger { void Log(string message); } [Export(typeof(ILogger))] class ConsoleLogger : ILogger { public void Log(string message) { Console.WriteLine("logger 1" + message); } } class Host { [Import] //延遲加載 Lazy<ILogger> _logger; //非延遲加載 //ILogger _logger; public Host() { var catalog = new AssemblyCatalog(this.GetType().Assembly); var container = new CompositionContainer(catalog); //如果不是延遲加載的話這兒會創建ConsoleLogger對象 container.ComposeParts(this); //非延遲加載 //_logger.Log("logworld"); //延遲加載 _logger.Value.Log("hello world"); } }}View Code當某一組件并不是立刻需要使用,或者內存開銷很大。影響程序加載的速度。比如當程序啟動的時候。這個時候我們可以使用延遲加載,也就是只有當程序用到的時候才會去加載該部件。我們可以使用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>包裝我們的導入類型。但是此時有個問題,就是當我們如果通過類型遍歷多個對象尋找可用導入時候,會創建所有對象。所以此時我們可以用元數據來判斷是否使我們需要的導入。

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); } //通過標記元數據來標記導出服務 [ExportMetadata("Name", "Console Logger")] [Export(typeof(ILogger))] class ConsoleLogger : ILogger { public void Log(string message) { Console.WriteLine("ConsoleLogger " + message); } } //通過標記元數據來標記導出服務 [ExportMetadata("Name", "DbLogger")] [Export(typeof(ILogger))] class DbLogger : ILogger { public void Log(string message) { Console.WriteLine("DbLogger " + message); } } public interface ILoggerData { string Name { get; } } 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"); } }}View Code
通過元數據可以匹配我們需要的導出服務。但是,通過單純的標記 [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://m.survivalescaperooms.com/santian/p/4357324.html
博客地址:http://m.survivalescaperooms.com/santian/
轉載請以超鏈接形式標明文章原始出處。新聞熱點
疑難解答