MEF 管理扩展框架

在本章中,我们将讨论管理扩展框架 (MEF)。 MEF 可用于第三方插件的可扩展性,或者它可以为常规应用程序带来松散耦合的类插件架构的优势。

  • MEF 是一个用于创建轻型、可扩展应用程序的库。

  • 它允许应用程序开发人员无需配置即可发现和使用扩展。

  • MEF 是 .NET Framework 4 不可或缺的一部分,在使用 .NET Framework 的任何地方都可用,它提高了大型应用程序的灵活性、可维护性和可测试性。

  • 您可以在客户端应用程序中使用 MEF,无论它们使用 Windows 窗体、WPF 还是任何其他技术,或者在使用 ASP.NET 的服务器应用程序中。

  • MEF 也已作为 Microsoft.Composition 移植到 .NET Core,但只是部分移植。

  • 只移植了System.CompositionSystem.ComponentModel.Composition还没有。 这意味着,我们没有目录可以从目录中的程序集中加载类型。

在本章中,我们将只学习如何在 .NET Core 应用程序中使用 MEF。

让我们了解一个简单的例子,我们将在 .NET Core 控制台应用程序中使用 MEF。 现在让我们创建一个新的 .NET Core 控制台项目。

在左窗格中,选择 Templates → Visual C# → .NET Core,然后在中间窗格中,选择控制台应用程序 (.NET Core)。

在名称字段中输入项目的名称,然后单击 OK。

名称字段

创建项目后,我们需要添加 Microsoft.Composition 的引用,以便我们可以使用 MEF。 为此,让我们在解决方案资源管理器和 Manage NuGet Packages… 中右键单击该项目

搜索 Microsoft.Composition 并单击 Install 安装。

Manage

单击 OK 确定按钮。

单击按钮

单击 I Accept 按钮。

Accept

当安装完成后,你会发现 References 中有一个错误。

Error References

让我们打开 project.json 文件。

{ 
   "version": "1.0.0-*", 
   "buildOptions": { 
      "emitEntryPoint": true 
   }, 
  
   "dependencies": { 
      "Microsoft.Composition": "1.0.30", 
      "Microsoft.NETCore.App": { 
         "type": "platform", 
         "version": "1.0.1" 
      } 
   }, 
  
   "frameworks": { 
      "netcoreapp1.0": { 
         "imports": "dnxcore50" 
      } 
   } 
}

可以看到添加了Microsoft.Composition依赖,但问题是这个包不兼容dnxcore50。 所以我们需要导入portablenet45+win8+wp8+wpa81。 现在让我们用以下代码替换您的 project.json 文件。

{ 
   "version": "1.0.0-*", 
   "buildOptions": { 
      "emitEntryPoint": true 
   }, 
   "dependencies": { 
      "Microsoft.Composition": "1.0.30", 
      "Microsoft.NETCore.App": { 
         "type": "platform", 
         "version": "1.0.1"
      } 
   }, 
   "frameworks": { 
      "netcoreapp1.0": { 
         "imports": "portable-net45+win8+wp8+wpa81" 
      } 
   } 
} 

保存此文件,您将看到错误已更正。

更正

如果展开引用,您将看到对 Microsoft.Composition 的引用。

Microsoft.Composition

首先我们需要创建一个要导出的接口并实现该接口,并用导出属性装饰类。 现在让我们添加一个新类。

在名称字段中输入您的班级名称,然后单击 Add

单击 Add

让我们在 PrintData.cs 文件中添加以下代码。

using System; 
using System.Collections.Generic; 
using System.Composition; 
using System.Linq; 
using System.Threading.Tasks; 
  
namespace MEFDemo { 
   public interface IPrintData { 
      void Send(string message); 
   } 
   [Export(typeof(IPrintData))] 
   public class PrintData : IPrintData { 
      public void Send(string message) { 
         Console.WriteLine(message); 
      } 
   } 
} 

如上所述,目录在 Microsoft.Composition 命名空间中不可用。 因此,它将使用 export 属性从 Assembly 加载所有类型,并附加到 import 属性,如 Program.cs 文件中的 Compose 方法所示。

using System; 
using System.Collections.Generic; 
using System.Composition; 
using System.Composition.Hosting; 
using System.Linq; 
using System.Reflection; 
using System.Threading.Tasks; 
  
namespace MEFDemo { 
   public class Program { 
      public static void Main(string[] args) { 
         Program p = new Program(); 
         p.Run(); 
      } 
      public void Run() { 
         Compose(); 
         PrintData.Send("Hello,this is MEF demo"); 
      } 
      [Import] 
      public IPrintData PrintData { get; set; } 
      
      private void Compose() { 
         var assemblies = new[] { typeof(Program).GetTypeInfo().Assembly }; 
         var configuration = new ContainerConfiguration() 
            .WithAssembly(typeof(Program).GetTypeInfo().Assembly); 
         
         using (var container = configuration.CreateContainer()) { 
            PrintData = container.GetExport<IPrintData>(); 
         } 
      } 
   } 
}

现在让我们运行您的应用程序,您将通过实例化 PrintData 类看到它正在运行。

PrintData

要了解更多关于 MEF 的信息,让我们访问以下 Url https://msdn.microsoft.com/en-us/library/dd460648%28v=vs.110%29.aspx 以获取更多详细信息。