You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 6 WPF Hybrid迁移中MEF的ImportMany无法工作求助

.NET 6 WPF Hybrid中MEF ImportMany集合为空的解决方法

问题描述

我正在将.NET Framework 4.6.2下的代码迁移至.NET 6 WPF Hybrid应用,使用MEF框架。容器已加载插件及元数据,但通过[ImportMany]标记的两个集合均为空,且未抛出任何异常。该插件在.NET Framework应用中可正常加载,求解决ImportMany无法工作的问题。

相关代码

PluginHandler类

public class PluginHandler
{
    [ImportMany(typeof(IKapprisWebViewerClientPlugin))]
    private static IEnumerable<Lazy<IKapprisWebViewerClientPlugin, IKapprisWebViewerClientPluginData>>? plugins { get; set; } = new List<Lazy<IKapprisWebViewerClientPlugin, IKapprisWebViewerClientPluginData>>();

    [ImportMany(typeof(IKapprisWebViewerClientPlugin))]
    private static IEnumerable<IKapprisWebViewerClientPlugin>? plugins1 { get; set; } = new List<IKapprisWebViewerClientPlugin>();

    public PluginHandler()
    {
        //An aggregate catalog that combines multiple catalogs
        var catalog = new AggregateCatalog();

        string exePath = System.Reflection.Assembly.GetExecutingAssembly().Location;
        string directory = new Uri(Path.GetDirectoryName(exePath)).LocalPath;

        //Adds all the parts found in all assemblies in 
        //the same directory as the executing program
        catalog.Catalogs.Add(
         new DirectoryCatalog(
          directory, "kwc*.dll"));

        //Create the CompositionContainer with the parts in the catalog
        CompositionContainer container = new CompositionContainer(catalog);

        //Fill the imports of this object
        container.ComposeParts(this);
        //container.SatisfyImportsOnce(this);

    }
}

插件类与元数据接口

[Export(typeof(IKapprisWebViewerClientPlugin))]
[ExportMetadata("Name", "IManage 10 / Cloud")]
public class WebViewerIntegration : WebViewerClientPlugin
{
 ...
}

public interface IKapprisWebViewerClientPluginData
{
    /// <summary>
    /// Name used to identify plugin
    /// </summary>
    string Name { get; }
}

解决步骤

  • 检查MEF包版本
    .NET 6需使用System.ComponentModel.Composition NuGet包,而非.NET Framework自带的MEF组件。确保项目已安装正确版本:执行Install-Package System.ComponentModel.Composition,避免混用旧版本组件。

  • 修正静态成员的导入问题
    MEF默认不支持导入静态属性,因为ComposeParts/SatisfyImportsOnce仅作用于实例对象,静态成员不在实例导入范围内。将两个集合改为非静态属性:

    [ImportMany(typeof(IKapprisWebViewerClientPlugin))]
    private IEnumerable<Lazy<IKapprisWebViewerClientPlugin, IKapprisWebViewerClientPluginData>>? plugins { get; set; } = new List<Lazy<IKapprisWebViewerClientPlugin, IKapprisWebViewerClientPluginData>>();
    
    [ImportMany(typeof(IKapprisWebViewerClientPlugin))]
    private IEnumerable<IKapprisWebViewerClientPlugin>? plugins1 { get; set; } = new List<IKapprisWebViewerClientPlugin>();
    
  • 验证元数据接口匹配性
    确保元数据接口IKapprisWebViewerClientPluginData被MEF正确识别:

    1. 接口必须是公共(public)的,且属性名称与ExportMetadata的键完全一致(此处为"Name")。
    2. 可通过自定义元数据属性增强识别性:
      [MetadataAttribute]
      [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
      public class KapprisWebViewerClientPluginDataAttribute : ExportAttribute, IKapprisWebViewerClientPluginData
      {
          public string Name { get; }
      
          public KapprisWebViewerClientPluginDataAttribute(string name) : base(typeof(IKapprisWebViewerClientPlugin))
          {
              Name = name;
          }
      }
      
      插件类改用自定义属性替代原有Export和ExportMetadata:
      [KapprisWebViewerClientPluginData("IManage 10 / Cloud")]
      public class WebViewerIntegration : WebViewerClientPlugin
      {
          // ...
      }
      
  • 确认插件程序集加载路径
    .NET 6中Assembly.GetExecutingAssembly().Location的返回路径可能与.NET Framework不同(比如单文件发布场景),改用AppContext.BaseDirectory获取应用根目录:

    string directory = AppContext.BaseDirectory;
    

    同时验证kwc*.dll是否存在于该目录,或指定完整路径排查加载问题。

  • 启用MEF调试验证
    添加代码查看容器加载的部件,确认插件是否被正确识别:

    var parts = catalog.Parts.ToList();
    foreach (var part in parts)
    {
        Console.WriteLine($"Loaded part: {part.ToString()}");
    }
    

    若未加载到插件,检查插件目标框架是否与主应用兼容(建议编译为.NET Standard 2.0或.NET 6),且无缺失依赖项。

  • 更换导入方法
    尝试将container.ComposeParts(this)替换为container.SatisfyImportsOnce(this),后者更适合一次性导入场景,避免潜在的部件重复组合问题。

内容的提问来源于stack exchange,提问作者user2903089

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 01:02:48