No Dependence Exception with MEF 2

I am studying MEF 2. The following is the exception:

An unhandled exception of type "System.Composition.Hosting.CompositionFailedException" occurred in System.Composition.TypedParts.dll

Additional Information: There is no dependency of "MessageSenders" on 'MEFStudy.Program'.

when calling the SatisfyImports () method. Why?

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"); } } } 

Update 1

According to there are 2 versions of MEF.

  • not portable with the .NET Framework
  • portable, available on nuget

The List<IMessageSender> approach works with the non-portable. But not portable. This is mistake?

+6
source share
2 answers

I accidentally changed the following code:

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

to

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

And he solves the problem.

But still, why? Not List<T> a IEnumerable<T> ?

ADD

And even a stranger, I changed IEnumerable to IList, it works. Why?

Possible explanation

(I would like to share my explanation with this.)

The following interface may produce exactly the same error.

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

This source of MEF 2 shows the reason.

enter image description here

The Equals () method of 3 SupportedContactTypes returns false with IMyList <>. Therefore, in MEF2 will not return a valid export for IMyList <>. And MEF 2 does not have a default value for a property decorated with the [ImportMany] attribute. Thus, in the following logic, the exception related to the dependency will be ignored.

enter image description here

So, we can say that the ImportMany attribute only supports an array and 3 supported generic types.

+2
source

This is too long for a comment:

I assume that MEF is intended to be used on interfaces, not specific classes. Thus, the lack of dependence on List, it seems to me, is a design choice, MEF just does not have an export definition for it.

In the case when you expect IMyList, the same mechanics apply: MEF does not have a specific type associated with this interface, which will be created because it does not have an export defined. Although the list meets all the requirements, it must be explicitly exported for IMyList. (This is convenient for unit testing, for example, since you just need to change your export to your Mock objects.)

0
source

Source: https://habr.com/ru/post/974809/


All Articles