MEF框架学习之旅(三)组合

1、框架中的Catalog

在MEF框架中,包含了4种Catalog,所有的Catalog的是从System.ComponentModel.Composition.Primitives名称空间下的ComposablePartCatalog抽象类派生下来。

 MEF框架学习之旅(三)组合

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、综合示例

解决方案如下:

 MEF框架学习之旅(三)组合

其中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框架学习之旅(一)概念

你可能感兴趣的:(框架)