程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> MEF筆記 之延遲加載,mef筆記延遲

MEF筆記 之延遲加載,mef筆記延遲

編輯:C#入門知識

MEF筆記 之延遲加載,mef筆記延遲


文章參考:在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://www.cnblogs.com/santian/p/4357324.html

博客地址:http://www.cnblogs.com/santian/

轉載請以超鏈接形式標明文章原始出處。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved