zoukankan      html  css  js  c++  java
  • MEF初体验之十:部件重组

    一些应用程序被设计成在运行时可以动态改变。例如,一个新的扩展被下载,或者因为其它的多种多样的原因其它的扩展变得不可用。MEF处理这些多样的场景是依赖我们称作重组的功能来实现的,它可已在最初的组合后改变导入的值。

    导入可以通知MEF它通过[Import]使用Allowrecomposition属性来支持重组。看下面的代码片段:

    [Export]
    public class HttpServerHealthMonitor
    {
        [ImportMany(AllowRecomposition=true)]
        public IMessageSender[] Senders { get; set; }
    }

    这告诉MEF,你的类准备来处理重组,并且,如果IMessageSender实现者可用性改变(一个新的实现者可用或不可用),这个集合将被改变以在catalog中反映此
    变化。一旦部件选择了允许重组,无论什么时候在catalog中可用的实现者有改变,或实例被手动地从容器中添加/移除,这些
    都将使可重组部件得到通知。

    重组的附加说明

    • 当重组发生时,我们将用一个新的实例来替换集合/数组的实例,我们将不会更新已存在的实例。在上面的例子中,如果一个新的IMessageSender实例出现了,Senders将被一个新的数组完全替换。这是为了促进现场安全。
    • 重组几乎对于支持导入的所有类型都有效,像字段,属性和集合,但是它不支持构造器参数。
    • 如果你的类型碰巧实现了IPartImportsSatisfiedNotification接口,无论重组何时发生,导入完成也将会被调用

    最后举个例子:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.Composition;
    using System.ComponentModel.Composition.Hosting;
    using System.Linq;
    using System.Reflection;
    using System.Text;
    using System.Threading.Tasks;
    using ClassLibrary2;
    using System.Timers;
    
    namespace RecompositionExample
    {
        class Program
        {
            [ImportMany(AllowRecomposition=true)]
            public IEnumerable<IMessageSender> Senders { get; set; }
            static void Main(string[] args)
            {
                Program p = new Program();
                p.Compose();
                p.Print();
                Console.ReadKey();
            }
            private AggregateCatalog catalog;
            private Timer t;
            void t_Elapsed(object sender, ElapsedEventArgs e)
            {
                catalog.Catalogs.Add(new DirectoryCatalog("Plugins", "*.dll"));
                t.Enabled = false;
                Console.WriteLine("-----------------");
                Print();
            }
            void Compose()
            {
                catalog = new AggregateCatalog(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
                var container = new CompositionContainer(catalog);
                container.ComposeParts(this);
                t = new Timer(5000);
                t.Elapsed += t_Elapsed;
                t.Start();
            }
            void Print()
            {
                foreach (var item in Senders)
                {
                    item.Send("Hi,MEF");
                }
            }
        }
        [Export(typeof(IMessageSender))]
        class EmailSender : IMessageSender
        {
            public void Send(string msg)
            {
                Console.WriteLine("Email sent:" + msg);
            }
        }
        class TcpSender : IMessageSender
        {
            public void Send(string msg)
            {
                throw new NotImplementedException();
            }
        }
    
    }
  • 相关阅读:
    Objective-C中#define的常见用法
    OpenGL ES为缓存提供数据的7个步骤
    绕指定点旋转算法
    矩阵平移旋转缩放公式
    矩阵和向量的乘法顺序
    干货集合
    RGB颜色空间与YCbCr颜色空间的互转
    UINavi中push控制器的时候隐藏TabBar
    CZLayer的阴影
    CALayer初认识
  • 原文地址:https://www.cnblogs.com/jellochen/p/3670504.html
Copyright © 2011-2022 走看看