Dot-Net

MEF 2 的“缺少依賴項”異常

  • September 16, 2014

我正在研究 MEF 2。下面的程式碼引發以下異常:

System.Composition.TypedParts.dll 中出現“System.Composition.Hosting.CompositionFailedException”類型的未處理異常

附加資訊:缺少對“MEFStudy.Program”的依賴“MessageSenders”。

呼叫 SatisfyImports() 方法時。為什麼?

using System;
using System.Collections.Generic;
using System.Composition;
using System.Composition.Hosting;


using System.Reflection;

namespace MEFStudy
{
   class Program
   {
       static void Main(string[] args)
       {
           Program p = new Program();
           p.Run();
       }

       [ImportMany]
       private List<IMessageSender> MessageSenders { get; set; }

       public void Run()
       {
           Compose();
           foreach (IMessageSender sender in MessageSenders)
           {
               sender.Send();
           }

       }

       private void Compose()
       {
           CompositionHost host = new ContainerConfiguration().WithAssembly(Assembly.GetExecutingAssembly()).CreateContainer();
           host.SatisfyImports(this);   // <=========== HERE
           host.Dispose();

       }
   }

   public interface IMessageSender
   {
       void Send();
   }

   [Export(typeof(IMessageSender))]
   public class EmailSender1 : IMessageSender
   {
       public void Send()
       {
           Console.WriteLine("EmailSender1");
       }
   }

   [Export(typeof(IMessageSender))]
   public class EmailSender2 : IMessageSender
   {
       public void Send()
       {
           Console.WriteLine("EmailSender2");
       }
   }

}

更新 1

根據here,MEF有2個版本。

  • .NET Framework 附帶的非攜帶式
  • NuGet 上提供的攜帶式

List<IMessageSender>方法適用於非攜帶式方法。但不是攜帶式的。這是一個錯誤嗎?

我不小心更改了以下程式碼:

[ImportMany]
private List<IMessageSender> MessageSenders { get; set; }

[ImportMany]
private IEnumerable<IMessageSender> MessageSenders { get; set; }

它解決了這個問題。

但是,為什麼?不是List<T>IEnumerable<T>

添加

更奇怪的是,我將 IEnumerable 更改為 IList,它可以工作。為什麼?

可能的解釋

(我想分享我對此的解釋。)

以下界面可以重現完全相同的錯誤。

interface IMyList<T> : IList<T>
{

}

[System.Composition.ImportMany] // MEF 2
private IMyList<IMessageSender> MessageSenders { get; set; }

以下 MEF 2 源顯示了原因。

在此處輸入圖像描述

3 SupportedContactTypes 的 Equals() 方法使用 IMyList<> 返回 false。所以在 MEF2 中不會返回 IMyList<> 的有效導出。並且 MEF 2 不允許使用裝飾的屬性的預設值

$$ ImportMany $$屬性。所以在下面的邏輯中,會拋出依賴缺失異常。 在此處輸入圖像描述

所以我們可以說,ImportMany 屬性只支持數組和支持的 3 種泛型類型。

引用自:https://stackoverflow.com/questions/25660013