2012-01-26 1 views
4

У меня есть класс Prim, который реализует интерфейс IPrimitiveDecomposer для MEF и наследует базовый класс Node.C#/MEF не работает с базовым классом без конструктора без параметров

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

Однако, когда я унаследовать класс, который не имеет конструктор без параметров, метод ComposeParts MEF (в) не может импортировать объект Prim. Я добавил атрибут ImportingConstructor после this page in MSDN, так как я получил ошибку компиляции без атрибута.

[Export(typeof(IPrimitiveDecomposer))] 
public class Prim : Node, IPrimitiveDecomposer 
{ 
    [ImportingConstructor] 
    public Prim(int val) : base (val) 
    {} 

    public bool Match(Node node) {return true;} 
} 

Код, который не работает, выглядит следующим образом. Когда вы предоставляете конструктор без параметров для класса Node, он работает.

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

ответ

9

ImportingConstructor Атрибут работает только тогда, когда параметры конструктору являются MEF экспортируются объекты. Конструкторы Prim(int val) не работают, потому что MEF не знает, какое значение должно предоставить конструктор.

Этот конкретный сценарий выглядит так, что он более подходит для заводского шаблона MEF.

interface IPrimitiveDecomposerFactory { 
    IPrimitiveDecomposer Create(int value); 
} 

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

Теперь код может импортировать IPrimitiveDecomposerFactory и использовать его для создания экземпляра IPrimitiveDecomposer на основе конкретных значений int

Смежные вопросы