C # / MEF does not work with base class without constructor without parameters

I have a Prim class that implements the IPrimitiveDecomposer interface for MEF and inherits the Node base class.

public class Node { public Node() { } } public interface IPrimitiveDecomposer { bool Match(Node node); } [Export(typeof(IPrimitiveDecomposer))] public class Prim : Node, IPrimitiveDecomposer { public bool Match(Node node) {return true;} } 

However, when I inherit a class that does not have a constructor without parameters, the MEF ComposeParts () method cannot import the Prim object. I added the ImportingConstructor attribute after this page on MSDN , since I received a compilation error without an attribute.

 [Export(typeof(IPrimitiveDecomposer))] public class Prim : Node, IPrimitiveDecomposer { [ImportingConstructor] public Prim(int val) : base (val) {} public bool Match(Node node) {return true;} } 

Code that does not work is as follows. When you provide a parameterless constructor for the Node class, it works.

 using System; using System.Collections.Generic; using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting; using System.Reflection; public class Node { public Node(int val) { } } public interface IPrimitiveDecomposer { bool Match(Node node); } [Export(typeof(IPrimitiveDecomposer))] public class Prim : Node, IPrimitiveDecomposer { [ImportingConstructor] public Prim(int val) : base (val) {} public bool Match(Node node) {return true;} } public class Test { [ImportMany(typeof(IPrimitiveDecomposer), AllowRecomposition = true)] private IEnumerable<IPrimitiveDecomposer> PrimitiveDecomposers { get; set; } void mef() { // MEF var catalog = new AggregateCatalog(); catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly())); var container = new CompositionContainer(catalog); container.ComposeParts(this); } static void Main() { var mef = new Test(); mef.mef(); var res = mef.PrimitiveDecomposers; foreach(var it in res) { Console.WriteLine(it); } } } 
+4
source share
1 answer

The ImportingConstructor attribute only works when the constructor parameters are exported MEF objects. Prim(int val) constructors do not work because MEF does not know what value the constructor should provide.

This particular scenario looks like it is much more suitable for the MEF factory template.

 interface IPrimitiveDecomposerFactory { IPrimitiveDecomposer Create(int value); } [Export(typeof(IPrimitiveDecomposerFactory))] sealed class PrimitiveDecomposerFactor : IPrimitiveDecomposerFactory { public IPrimitiveDecomposer Create(int value) { return new Prim(value); } } 

Now the code can import IPrimitiveDecomposerFactory and use it to instantiate IPrimitiveDecomposer based on specific int values

+9
source

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


All Articles