Fork me on GitHub

MEF(Managed Extensibility Framework)快速入门与实战Demo

MEF(Managed Extensibility Framework)快速入门与实战Demo

一、什么是 MEF?

MEF,全称 Managed Extensibility Framework,是 .NET 提供的一个模块化依赖注入框架
它最大的特点就是 —— 让程序能够动态发现和加载模块,而无需在代码中显式引用具体实现类。

可以理解为:

你只定义“接口”和“能力”,实现类可以来自任何地方(甚至是单独的DLL插件),程序会自动把它们装配起来。

说人话:

你只要实现某个接口,在你的实现类上面做Export标记,程序启动时将会找到这些实现并自动执行,可选择全部执行还是只执行第一个。


 

二、MEF 的核心概念

关键特性说明
[Export] 把一个类标记为可被“导出”(即别人可以引用)
[Import] / [ImportMany] 声明一个依赖(由 MEF 自动注入)
CompositionContainer MEF 的“依赖容器”,负责扫描和装配
PartCreationPolicy 控制生命周期(Shared / NonShared)

三、简单示例思路

我们想做一个简单的架构:

 
Program → Startup → IServiceController → ServiceController → IWcfServiceHost → WcfServiceHost

最终目标:

  • 启动程序后,自动发现并启动所有实现了 IServiceController 的模块。

  • 可以方便扩展其他模块,比如 CameraService、PlcService 等。


四、完整代码示例

📁 目录结构:

MEFDemo
├── Program.cs
├── Startup.cs
├── Contracts
│  ├── IServiceController.cs
│  └── IWcfServiceHost.cs
└── Services
  ├── ServiceController.cs
  └── WcfServiceHost.cs


🧠 1️⃣ 定义接口(Contracts)

// Contracts/IServiceController.cs
public interface IServiceController
{
    void Start();
    void Stop();
}

// Contracts/IWcfServiceHost.cs
public interface IWcfServiceHost
{
    void Start();
    void Stop();
}

⚙️ 2️⃣ 实现服务(Services)

using System;
using System.ComponentModel.Composition;
using System.Threading;

[Export(typeof(IWcfServiceHost))]
[PartCreationPolicy(CreationPolicy.Shared)]
public class WcfServiceHost : IWcfServiceHost
{
    private bool _running;

    public void Start()
    {
        _running = true;
        Console.WriteLine("[WcfServiceHost] 启动服务...");
        new Thread(() =>
        {
            while (_running)
            {
                Console.WriteLine("WCF 服务正在运行中...");
                Thread.Sleep(2000);
            }
        })
        { IsBackground = true }.Start();
    }

    public void Stop()
    {
        _running = false;
        Console.WriteLine("[WcfServiceHost] 服务已停止。");
    }
}

🔩 3️⃣ 服务控制器(ServiceController)

using System;
using System.ComponentModel.Composition;

[Export(typeof(IServiceController))]
[PartCreationPolicy(CreationPolicy.Shared)]
internal class ServiceController : IServiceController
{
    private readonly IWcfServiceHost _wcfService;

    [ImportingConstructor]
    public ServiceController(IWcfServiceHost wcfService)
    {
        _wcfService = wcfService;
    }

    public void Start()
    {
        Console.WriteLine("[ServiceController] 启动所有服务...");
        _wcfService.Start();
    }

    public void Stop()
    {
        Console.WriteLine("[ServiceController] 停止所有服务...");
        _wcfService.Stop();
    }
}

🧭 4️⃣ 启动器(Startup)

 
using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;

public class Startup
{
    private CompositionContainer _container;

    [Import(typeof(IServiceController))]
    public IServiceController ServiceController { get; set; }

    public void Start()
    {
        Console.WriteLine("[Startup] 初始化 MEF 组件...");
     //启动匹配到的默认第一个实现 ServiceController = MefContainer.Instance.GetExportedValue<IServiceController>();
     ServiceController.Start();
      //匹配到的所有实现都执行
     //var allServices = MefContainer.Instance.GetExportedValues<IServiceController>();
     //foreach (var service in allServices)
       //service.Start();
    }

    public void Stop()
    {
        ServiceController.Stop();
    }
}

🚀 5️⃣ 主程序(Program)

 
using System;

class Program
{
    static void Main()
    {
        var startup = new Startup();
        startup.Start();

        Console.WriteLine("按下 Ctrl+C 停止程序...");
        Console.CancelKeyPress += (s, e) =>
        {
            e.Cancel = true;
            startup.Stop();
            Environment.Exit(0);
        };

        while (true)
            System.Threading.Thread.Sleep(1000);
    }
}
 

🚀 ⑥ MEF 拓展优化(MefContainer)

using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Reflection;

/// <summary>
///     A MEF implementation of the IOC container in singleton pattern.
/// </summary>
[Export(typeof(ICompositionContainer))]
[PartCreationPolicy(CreationPolicy.Shared)]
public class MefContainer : IocContainer
{
    #region Constants and Fields

    private static MefContainer _container;

    #endregion

    #region Constructors and Destructors

    private MefContainer()
    {
        var catalog = new AggregateCatalog();

        catalog.Catalogs.Add(new DirectoryCatalog(".", "*.dll"));

        var entryAssembly = Assembly.GetEntryAssembly();
        if (entryAssembly != null)
        {
            catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetEntryAssembly()));
        }

        Container = new CompositionContainer(catalog);
    }

    #endregion

    #region Public Properties

    /// <summary>
    ///     Gets the IOC container as singleton.
    /// </summary>
    public static ICompositionContainer Instance
    {
        get
        {
            if (_container == null)
            {
                _container = new MefContainer();
                _container.ComposeExportedValue(_container);
                MefInstanceProvider.SetContainer(_container);
            }

            return _container;
        }
    }

    #endregion
}

  

 

五、运行效果

 
[Startup] 初始化 MEF 组件...
[ServiceController] 启动所有服务...
[WcfServiceHost] 启动服务...
WCF 服务正在运行中...
WCF 服务正在运行中...
(Ctrl+C 停止)
[ServiceController] 停止所有服务...
[WcfServiceHost] 服务已停止。

六、总结与思考 💡

优点缺点
✅ 完全解耦,模块可独立更新或热插拔 ❌ 不支持复杂的生命周期管理
✅ 无需手动注册类型 ❌ 性能略逊于主流 IoC
✅ 非常适合插件化、服务化结构 ❌ 不支持构造函数链式注入(需要导入属性或构造标记)

MEF 是一种轻量、原生、面向插件的依赖注入机制。
如果项目需要“自动发现模块 + 松耦合扩展”,它非常适合。

posted @ 2025-11-13 10:11  WantRemake  阅读(17)  评论(0)    收藏  举报