zoukankan      html  css  js  c++  java
  • MEF 编程指南(三):声明导出

    组合部件通过 [System.ComponentModel.Composition.ExportAttribute] 特性声明导出。MEF 有几种不同的方式声明导出,包括在部件层面(Part Level),通过属性(Properties)和方法(Method)声明导出。
     
     
    组合部件导出(Composable Part Exports)
     
     
    当组合部件需要导出自身时候使用组合部件层面导出。为了组合部件导出自身,如下例代码所示,仅仅利用 [System.ComponentModel.Composition.ExportAttribute] 特性标识组合部件。
     
        public class SomeComposablePart { }
     
     
    属性导出(Property Exports)
     
    部件也可导出属性。属性导出的优势有几点原因。
     
     
    • 允许导出密封类(Sealed Types),比如:核心 CLR 类型,或者其他三方类型。
    • 允许如何创建导出中解耦。比如:导出运行时(Runtime)为你创建存在的 HttpContext。
    • 允许相同的组合部件拥有继承关系的导出,比如:DefaultSendersRegistry 组合部件导出默认的一组 Sender 作为属性。
     
     
    如下例:可能有一个配置类(Configuration Class)导出一个整形(Integer)的“TImeout”契约。
     
        public class Configuration
        {
            [Export("Timeout")]
            public int Timeout
            {
                get { return int.Parse(ConfigurationManager.AppSettings["Timeout"]); }
            }
        }
     
        [Export]
        public class UsesTimeout
        {
            [Import("Timeout")]
            public int Timeout { get; set; }
     
            public UsesTimeout()
            {
                Compose();
            }
     
            private void Compose()
            {
                //var container = new CompositionContainer();
                //container.ComposeParts(this, new EmailSender());
                AssemblyCatalog catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
                var container = new CompositionContainer(catalog);
                container.ComposeParts(this);
            }
        }
     
     
    方法导出(Method Exports)
     
    方法导出是指部件导出其中一个方法。方法指定为导出契约,作为委托(Delegates)被导出。方法导出包括下面的许多优势。
     
     
     
    • 允许更细力度的控制导出什么。比如:规则引擎(Rules Engine)可能导入一组可插拔(Pluggable)的方法导出。
    • 规避了调用者对类型的认知情况。
    • 可以通过 Light Code Gen 生成,which you cannot do with the other exports。
     
    注意:由于框架限制,方法导出不能超出4个参数。

    下面的例子中,MessageSender 类的 Send 方法作为 Action<string> 委托导出。Processor 类导入同样的委托。
     
        public class MessageSender
        {
            [Export(typeof(Action<string>))]
            public void Send(string message)
            {
                Console.WriteLine(message);
            }
        }
     
        [Export]
        public class Processor
        {
            [Import(typeof(Action<string>))]
            public Action<string> MessageSender { get; set; }
     
            public void Send()
            {
                MessageSender("Processed");
            }
     
            public Processor()
            {
                Compose();
            }
     
            private void Compose()
            {
                //var container = new CompositionContainer();
                //container.ComposeParts(this, new EmailSender());
                AssemblyCatalog catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
                var container = new CompositionContainer(catalog);
                container.ComposeParts(this);
            }
        }
     
     
    你也可以使用简单字符约束(Simple String Contract)导出导入方法。例如:下面的“Sender”约束的使用。
     
        public class MessageSender
        {
            [Export("MessageSender")]
            public void Send(string message)
            {
                Console.WriteLine(message);
            }
        }
     
        [Export]
        public class Processor
        {
            [Import("MessageSender")]
            public Action<string> MessageSender { get; set; }
     
            public void Send()
            {
                MessageSender("Processed");
            }
     
            public Processor()
            {
                Compose();
            }
     
            private void Compose()
            {
                //var container = new CompositionContainer();
                //container.ComposeParts(this, new EmailSender());
                AssemblyCatalog catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
                var container = new CompositionContainer(catalog);
                container.ComposeParts(this);
            }
        }
     
    注意:当做方法导出时,必须提供类型或者字符约束名,而不能留空。
     
    继承导出
     
    MEF 支持基类/接口定义导出,由实现者自动继承的能力。利用 MEF 和遗留框架集成,但是又不想修改现有的客户代码,这是理想的。System.ComponentModel.Composition.InheritedExportAttribute 特性提供这种能力。例如:ILogger 标识了继承导出的特性。Logger 实现了 ILogger,因此自动实现了 ILogger 的导出。
     
        [InheritedExport]
        public interface ILogger
        {
            void Log(string message);
        }
     
        public class Logger : ILogger
        {
            public void Log(string message) { }
        }
     
     
    发现非公开(Non-Public)组合部件
     
    MEF 支持发现公开和非公开的部件。你无须为了这种用法做任何事情。请注意:在 medium/partial trust 环境(包括 Sliverlight)非公开组合将不被支持。
     
  • 相关阅读:
    234树(2)实现
    矩阵的坐标变换(转)
    OpenGL 学习笔记(3)绘制几何物体
    OpenGL 学习笔记(1)初始化窗体
    OpenGL学习笔记(5)3D基本概念
    矩阵的三维变换(转)
    OpenGL 学习笔记(2)创建第一个图形
    234树(1)概念
    OpenGL 学习笔记(4)顶点数组
    OpenGL学习笔记(6)第一个动画
  • 原文地址:https://www.cnblogs.com/JavCof/p/3670304.html
Copyright © 2011-2022 走看看