zoukankan      html  css  js  c++  java
  • C#可扩展编程之MEF学习笔记(四):见证奇迹的时刻

    前面三篇讲了MEF的基础和基本到导入导出方法,下面就是见证MEF真正魅力所在的时刻。如果没有看过前面的文章,请到我的博客首页查看。

      前面我们都是在一个项目中写了一个类来测试的,但实际开发中,我们往往要采用分层架构,就拿最简单的三层架构来说吧,我们通常把业务逻辑写在DLL中,现在就来写一个例子,看看如何在不编译整个项目的情况下,轻松的实现扩展。先透露一下,我们只要添加一个DLL就可以了。

      这里就以银行为例子吧,首先新建一个控制台项目,还叫MEFDemo吧,然后建一个类库写接口,然后再建一个类库实现接口。项目结构如下:

    MEFDemo和BankOfChina都只引用接口项目,MEFDemo不需要引用BankOfChina。

    BankInterface的代码如下,做个简单实例,写几个方法测试一下:

    复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace BankInterface
    {
       public interface ICard
       {
          //账户金额
          double Money { get; set; }
          //获取账户信息
          string GetCountInfo();
          //存钱
          void SaveMoney(double money);
          //取钱
          void CheckOutMoney(double money);
       }
    }
    复制代码

    这里添加一个中国银行卡,实现接口,引用命名空间什么的不再重复说了,不懂看前面的文章,代码如下:

    复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using BankInterface;
    using System.ComponentModel.Composition;
    
    namespace BankOfChina
    {
       [Export(typeof(ICard))]
       public class ZHCard : ICard
       {
          public string GetCountInfo()
          {
             return "Bank Of China";
          }
    
          public void SaveMoney(double money)
          {
             this.Money += money;
          }
    
          public void CheckOutMoney(double money)
          {
             this.Money -= money;
          }
    
          public double Money { get; set; }
       }
    }
    复制代码

    然后编写主程序,代码如下:

    复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Reflection;
    using System.ComponentModel.Composition;
    using System.ComponentModel.Composition.Hosting;
    using BankInterface;
    
    namespace MEFDemo
    {
       class Program
       {
          [ImportMany(typeof(ICard))]
          public IEnumerable<ICard> cards { get; set; }
    
          static void Main(string[] args)
          {
             Program pro = new Program();
             pro.Compose();

          foreach (var c in pro.cards)
          {
             Console.WriteLine(c.GetCountInfo());
          }

    
             Console.Read();
          }
    
          private void Compose()
          {
             var catalog = new DirectoryCatalog("Cards");
             var container = new CompositionContainer(catalog);
             container.ComposeParts(this);
          }
       }
    }
    复制代码

    现在,我们知道只有一种银行卡,及中国银行的,注意我标红的代码,这里是一个目录,及主程序所在目录的Cards文件夹,我们把生成的BankOfChian.dll拷贝到这个文件夹下,然后运行才可以正确输出信息(毕竟我们没有引用那个项目),如图:

    到了这里相信大家已经明白了,如果现在需求改变了,需要支持建行、农行等银行卡,怎么办呢?通常我们要改项目,把整个项目都编译再重新发布。但是现在不需要这么做了,我们只需要添加一个类库项目,把生成的dll拷贝到Cards目录下即可。

    我们在这个解决方案下继续添加一个类库项目,实现ICard接口,代码如下:

    复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ComponentModel.Composition;
    using BankInterface;
    
    namespace NongHang
    {
       [Export(typeof(ICard))]
       public class NHCard : ICard
       {
          public string GetCountInfo()
          {
             return "Nong Ye Yin Hang";
          }
    
          public void SaveMoney(double money)
          {
             this.Money += money;
          }
    
          public void CheckOutMoney(double money)
          {
             this.Money -= money;
          }
    
          public double Money { get; set; }
       }
    }
    复制代码

    点击右键编译,把生成的dll拷贝到Cards目录下面,运行看到如下结果:

    再看看Cards目录中,现在你添加几个dll,就会显示多少条信息了。

  • 相关阅读:
    移动端div移动
    js获取网页高度
    css cursor 的可选值(鼠标的各种样式)
    HTML5 拖动
    函数式编程中的常用技巧
    CoolShell Puzzle攻略[更新隐藏剧情]
    Web性能测试-词汇
    STM32库函数 断言机制 宏定义assert_param(expr)和assert_failed的使用方法
    arm汇编:伪指令ldr分析
    Altium designer 16 Mechanical1层之PCB 打样说明
  • 原文地址:https://www.cnblogs.com/ljdong7/p/12107716.html
Copyright © 2011-2022 走看看