MEF框架學習之旅(三)組合


1、框架中的Catalog

在MEF框架中,包含了4種Catalog,所有的Catalog的是從System.ComponentModel.Composition.Primitives名稱空間下的ComposablePartCatalog抽象類派生下來。

 

AssemblyCatalog:表示從程序集中搜索部件的目錄。

DirectoryCatalog:表示從文件系統的指定路徑中,搜索程序集,從而搜索部件。

TypeCatalog:表示從指定的類型集合中,去搜索相應的部件。

AggregateCatalog:聚合目錄,可以添加上面所說的所有目錄,從而進行多方面的部件搜索。

直接添加部件到容器:

 在CompositionContainer類里里通過重載方法ComposeParts()手動添加每個組成部件。下面的例子里一個LoggerProxy的實例和當前要導入的Program實例一起添加到容器

代碼段

   container.ComposeParts(this, new LoggerProxy());

 

 

2、自定義Catalog

自定義Catalog和系統實現的Catalog類似,我們通過繼承System.ComponentModel.Composition.Primitives空間下的ComposablePartCatalog類,並且覆寫掉基類的方法即可。

 要實現自己的Catalog,必須要覆寫掉Parts屬性,如有特別需要處理的,我們還可以覆寫GetExports方法,此方法默認的調用了Parts屬性,進行進一步的輸出。

例如實現目錄過濾篩選功能:

在使用MEF目錄進行導出部件托管的時候,在某些需求下或許只需要其中的一個部件,這種情況可以通過遍歷部件集合得到。然而MEF也為此提供了一種解決方案,那就是使用目錄過濾篩選功能。MEF中的ComposablePartCatalog類和INotifyComposablePartCatalogChanged接口就是專門用來實現目錄篩選的,可以如下代碼段中演示的對目錄過濾的封裝。

代碼段

        public class FilteredCatalog : ComposablePartCatalog, INotifyComposablePartCatalogChanged
        {
            private readonly ComposablePartCatalog _inner;
            private readonly INotifyComposablePartCatalogChanged _innerNotifyChange;
            private readonly IQueryable<ComposablePartDefinition> _partsQuery;


            public FilteredCatalog(ComposablePartCatalog inner,
                                Expression<Func<ComposablePartDefinition, bool>> expression)

            {
                _inner = inner;

                _innerNotifyChange = inner as INotifyComposablePartCatalogChanged;

               _partsQuery = inner.Parts.Where(expression);

            }


            public event EventHandler<ComposablePartCatalogChangeEventArgs> Changed
            {

                add
                {
                    if (_innerNotifyChange != null)
                        _innerNotifyChange.Changed += value;

                }
                remove
                {
                    if (_innerNotifyChange != null)

                       _innerNotifyChange.Changed -= value;
                }
             }


            public event EventHandler<ComposablePartCatalogChangeEventArgs> Changing
            {
                add
                {
                    if (_innerNotifyChange != null)
                        _innerNotifyChange.Changing += value;
                }
                remove
                {

                    if (_innerNotifyChange != null)

                        _innerNotifyChange.Changing -= value;
                }

            }
            public override System.Linq.IQueryable<ComposablePartDefinition> Parts
            {

                get
                {
                    return _partsQuery;
                }
            }
        }

 

 

3、綜合示例

解決方案如下:

 

其中MEFParts為一個類庫項目,並且生成輸出路徑是在MyConsoleMEF輸出路徑下的Parts目錄中。

Program中,我們輸出了所有的Part,代碼如下:

代碼段

   class Program
    {
        private static CompositionContainer container;

        [ImportMany]
        public ILogger[] Loggers { get; private set; }

        static void Main(string[] args)
        {

            Program p = new Program();


            //AssemblyCatalog:表示從程序集中搜索部件的目錄
            var assemblyCatalog = new AssemblyCatalog(typeof(Program).Assembly);
            //相當於var assemblyCatalog = new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly());
            //DirectoryCatalog:表示從文件系統的指定路徑中,搜索程序集,從而搜索部件
            var directoryCatalog = new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory + "\\Parts", "*.dll");
            //TypeCatalog:表示從指定的類型集合中,去搜索相應的部件
           var typeCatalog = new TypeCatalog(typeof(ConsoleLogger));
            //AggregateCatalog:聚合目錄,可以添加上面所說的所有目錄,從而進行多方面的部件搜索
            var aggregateCatalog = new AggregateCatalog(assemblyCatalog, directoryCatalog, typeCatalog);

            container = new CompositionContainer(aggregateCatalog);

            var exports = container.GetExports<ILogger>();
            foreach (var exportValue in exports)
            {

                Console.WriteLine(exportValue.Value.GetType());

            }
             Console.Read();
        }
   }

 

相關閱讀:

MEF框架學習之旅(十一)調試

MEF框架學習之旅(十)重組

MEF框架學習之旅(九)部件生命周期及組裝通知

MEF框架學習之旅(八)避免發現

MEF框架學習之旅(七)部件的創建規則(策略)

MEF框架學習之旅(六)元數據和元數據視圖

MEF框架學習之旅(五)導入導出(下)

MEF框架學習之旅(四)導入導出(上)

MEF框架學習之旅(三)組合

MEF框架學習之旅(二)契約

MEF框架學習之旅(一)概念


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM