C#可扩展编程之MEF学习笔记(三):导出类的方法和属性

简介:   前面说完了导入和导出的几种方法,如果大家细心的话会注意到前面我们导出的都是类,那么方法和属性能不能导出呢???答案是肯定的,下面就来说下MEF是如何导出方法和属性的。   还是前面的代码,第二篇中已经提供了下载链接,大家可以下载学习。

  前面说完了导入和导出的几种方法,如果大家细心的话会注意到前面我们导出的都是类,那么方法和属性能不能导出呢???答案是肯定的,下面就来说下MEF是如何导出方法和属性的。

  还是前面的代码,第二篇中已经提供了下载链接,大家可以下载学习。

  首先来说导出属性,因为这个比较简单,和导出类差不多,先来看看代码,主要看我加注释的地方,MusicBook.cs中的代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Composition;

namespace MEFDemo
{
   [Export("MusicBook")]
   public class MusicBook : IBookService
   {
      //导出私有属性
      [Export(typeof(string))]
      private string _privateBookName = "Private Music BookName";

      //导出公有属性
      [Export(typeof(string))]
      public string _publicBookName = "Public Music BookName";


      public string BookName { get; set; }

   }

   [Export("MathBook", typeof(IBookService))]
   public class MathBook : IBookService
   {
      public string BookName { get; set; }

      public string GetBookName()
      {
         return "MathBook";
      }
   }

   [Export("HistoryBook", typeof(IBookService))]
   public class HistoryBook : IBookService
   {
      public string BookName { get; set; }

      public string GetBookName()
      {
         return "HistoryBook";
      }
   }

}

program.cs中的代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;

namespace MEFDemo
{
   class Program
   {
      [ImportMany("MathBook")]
      public IEnumerable<object> Services { get; set; }

      //导入属性,这里不区分public还是private
      [ImportMany]
      public List<string> InputString { get; set; }

      static void Main(string[] args)
      {
         Program pro = new Program();
         pro.Compose();
         if (pro.Services != null)
         {
            foreach (var s in pro.Services)
            {
               var ss = (IBookService)s;
               Console.WriteLine(ss.GetBookName());
            }
         }
         foreach (var str in pro.InputString)
         {
            Console.WriteLine(str);
         }

         Console.Read();
      }
      
      private void Compose()
      {
         var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
         CompositionContainer container = new CompositionContainer(catalog);
         container.ComposeParts(this);
      }
   }
}

下面还用foreach遍历输出属性的值,运行即可查看到结果。最后我会附上源码供大家下载,这里就不再截图了。

下面说导出方法吧,同理无论是公有方法还是私有方法都是可以导出的,MusicBook代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Composition;

namespace MEFDemo
{
   [Export("MusicBook")]
   public class MusicBook : IBookService
   {
      //导出私有属性
      [Export(typeof(string))]
      private string _privateBookName = "Private Music BookName";

      //导出公有属性
      [Export(typeof(string))]
      public string _publicBookName = "Public Music BookName";


      public string BookName { get; set; }

      //导出公有方法
      [Export(typeof(Func<string>))]
      public string GetBookName()
      {
         return "MusicBook";
      }

      //导出私有方法
      [Export(typeof(Func<int, string>))]
      private string GetBookPrice(int price)
      {
         return "$" + price;
      }
   }

   [Export("MathBook", typeof(IBookService))]
   public class MathBook : IBookService
   {
      public string BookName { get; set; }

      public string GetBookName()
      {
         return "MathBook";
      }
   }

   [Export("HistoryBook", typeof(IBookService))]
   public class HistoryBook : IBookService
   {
      public string BookName { get; set; }

      public string GetBookName()
      {
         return "HistoryBook";
      }
   }

}

program中的代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;

namespace MEFDemo
{
   class Program
   {
      [ImportMany("MathBook")]
      public IEnumerable<object> Services { get; set; }

      //导入属性,这里不区分public还是private
      [ImportMany]
      public List<string> InputString { get; set; }

      //导入无参数方法
      [Import]
      public Func<string> methodWithoutPara { get; set; }

      //导入有参数方法
      [Import]
      public Func<int,string> methodWithPara { get; set; }

      static void Main(string[] args)
      {
         Program pro = new Program();
         pro.Compose();
         if (pro.Services != null)
         {
            foreach (var s in pro.Services)
            {
               var ss = (IBookService)s;
               Console.WriteLine(ss.GetBookName());
            }
         }
         foreach (var str in pro.InputString)
         {
            Console.WriteLine(str);
         }

         //调用无参数方法
         if (pro.methodWithoutPara != null)
         {
            Console.WriteLine(pro.methodWithoutPara());
         }
         //调用有参数方法
         if (pro.methodWithPara != null)
         {
            Console.WriteLine(pro.methodWithPara(3000));
         }

         Console.Read();
      }
      
      private void Compose()
      {
         var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
         CompositionContainer container = new CompositionContainer(catalog);
         container.ComposeParts(this);
      }
   }
}

导入导出方法用到了Func<T>委托,当然没有返回值的话可以用Action<T>委托,关于委托这里就不多说了,大家可以自行百度。

点击这里下载源码

 

MEF系列文章:

 C#可扩展编程之MEF学习笔记(一):MEF简介及简单的Demo

C#可扩展编程之MEF学习笔记(二):MEF的导出(Export)和导入(Import)

C#可扩展编程之MEF学习笔记(三):导出类的方法和属性

C#可扩展编程之MEF学习笔记(四):见证奇迹的时刻

C#可扩展编程之MEF学习笔记(五):MEF高级进阶

 

目录
相关文章
|
9天前
|
存储 安全 编译器
学懂C#编程:属性(Property)的概念定义及使用详解
通过深入理解和使用C#的属性,可以编写更清晰、简洁和高效的代码,为开发高质量的应用程序奠定基础。
49 12
|
1天前
|
C#
基于 C# 编写的 Visual Studio 文件编码显示与修改扩展插件
基于 C# 编写的 Visual Studio 文件编码显示与修改扩展插件
|
1月前
|
JSON 程序员 C#
使用 C# 比较两个对象是否相等的7个方法总结
比较对象是编程中的一项基本技能,在实际业务中经常碰到,比如在ERP系统中,企业的信息非常重要,每一次更新,都需要比较记录更新前后企业的信息,直接比较通常只能告诉我们它们是否指向同一个内存地址,那我们应该怎么办呢?分享 7 个方法给你!
|
1月前
|
C# UED SEO
C# 异步方法async / await任务超时处理
通过使用 `Task.WhenAny`和 `Task.Delay`方法,您可以在C#中有效地实现异步任务的超时处理机制。这种方法允许您在指定时间内等待任务完成,并在任务超时时采取适当的措施,如抛出异常或执行备用操作。希望本文提供的详细解释和代码示例能帮助您在实际项目中更好地处理异步任务超时问题,提升应用程序的可靠性和用户体验。
74 3
|
1月前
|
C# Python
使用wxpython开发跨平台桌面应用,对wxpython控件实现类似C#扩展函数处理的探究
【10月更文挑战第30天】使用 `wxPython` 开发跨平台桌面应用时,可以通过创建辅助类来模拟 C# 扩展函数的功能。具体步骤包括:1. 创建辅助类 `WxWidgetHelpers`;2. 在该类中定义静态方法,如 `set_button_color`;3. 在应用中调用这些方法。这种方法提高了代码的可读性和可维护性,无需修改 `wxPython` 库即可为控件添加自定义功能。但需要注意显式调用方法和避免命名冲突。
|
2月前
|
存储 C#
【C#】大批量判断文件是否存在的两种方法效率对比
【C#】大批量判断文件是否存在的两种方法效率对比
52 1
|
2月前
|
Java 程序员 C#
【类的应用】C#应用之派生类构造方法给基类构造方法传参赋值
【类的应用】C#应用之派生类构造方法给基类构造方法传参赋值
16 0
|
1月前
|
C# 开发者
C# 一分钟浅谈:Code Contracts 与契约编程
【10月更文挑战第26天】本文介绍了 C# 中的 Code Contracts,这是一个强大的工具,用于通过契约编程增强代码的健壮性和可维护性。文章从基本概念入手,详细讲解了前置条件、后置条件和对象不变量的使用方法,并通过具体代码示例进行了说明。同时,文章还探讨了常见的问题和易错点,如忘记启用静态检查、过度依赖契约和性能影响,并提供了相应的解决建议。希望读者能通过本文更好地理解和应用 Code Contracts。
41 3
|
1月前
|
设计模式 C# 图形学
Unity 游戏引擎 C# 编程:一分钟浅谈
本文介绍了在 Unity 游戏开发中使用 C# 的基础知识和常见问题。从 `MonoBehavior` 类的基础用法,到变量和属性的管理,再到空引用异常、资源管理和性能优化等常见问题的解决方法。文章还探讨了单例模式、事件系统和数据持久化等高级话题,旨在帮助开发者避免常见错误,提升游戏开发效率。
59 4
|
3月前
|
API C#
C# 一分钟浅谈:文件系统编程
在软件开发中,文件系统操作至关重要。本文将带你快速掌握C#中文件系统编程的基础知识,涵盖基本概念、常见问题及解决方法。文章详细介绍了`System.IO`命名空间下的关键类库,并通过示例代码展示了路径处理、异常处理、并发访问等技巧,还提供了异步API和流压缩等高级技巧,帮助你写出更健壮的代码。
54 2