2011-01-17 4 views
1

Я думаю, что теряю рассудок. :) Я уже два дня борется с этим. Код выглядит правильно. Но по какой-то причине, когда я пытаюсь получить доступ к полю [ImportMany], он является нулевым или, по крайней мере, не возвращает никаких значений.MEF Пользовательские атрибуты и Lazy

Это 3 части в каталоге, но они не применяются к Lazy [] import, который я определяю.

Вот мой код:

using System; 
using System.Linq; 
using System.ComponentModel.Composition; 
using System.ComponentModel.Composition.Hosting; 

namespace MefTest 
{ 

// Extension interface and metadata 

    public interface IUIExtension 
    { 
     void DoSomething(); 
    } 

    public interface IUIExtensionDetails 
    { 
     string Name { get; } 
     string Uri { get; } 
    } 

    [MetadataAttribute] 
    [AttributeUsage(AttributeTargets.Class, AllowMultiple=false)] 
    public class UIExtensionAttribute : ExportAttribute 
    { 
     public UIExtensionAttribute() : base(typeof(IUIExtensionDetails)) { } 

     public string Name { get; set; } 
     public string Uri { get; set; } 
    } 

     // Extensions 

    [UIExtension(Name="Test 01", Uri="http://www.yourmomma.com/")] 
    public class Test1Extension : IUIExtension 
    { 
     public void DoSomething() { } 
    } 

    [UIExtension(Name = "Test 02", Uri = "http://www.yourdaddy.com/")] 
    public class Test2Extension : IUIExtension 
    { 
     public void DoSomething() { } 
    } 

    [UIExtension(Name = "Test 03", Uri = "http://www.youruncle.com/")] 
    public class Test3Extension : IUIExtension 
    { 
     public void DoSomething() { } 
    } 

     // Main program 

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

     [ImportMany] 
     public Lazy<IUIExtension, IUIExtensionDetails>[] Senders { get; set; } 

     public void Run() 
     { 
      Compose(); 
     } 

     public void Compose() 
     { 
      var catalog = new AssemblyCatalog(
       System.Reflection.Assembly.GetExecutingAssembly()); 
      var container = new CompositionContainer(catalog); 

      container.ComposeParts(this); 

      // This is always 3 
      Console.WriteLine(
       (from g in container.Catalog.Parts select g).Count()); 
      // This is always 0 
      Console.WriteLine(Senders.Length); 

      Console.ReadKey(); 
     } 
    } 

} 

ответ

2

Ваш атрибут метаданных является определение экспорта, typeof(IUIExtensionDetails) который является ваш контракт метаданных, а не фактическое значение расширения. Изменение пользовательских атрибутов конструктор:

public UIExtensionAttribute() : base(typeof(IUIExtension)) { } 
+0

+1 Благодарю вас, вы правы. –

3

Ваша ошибка здесь:

public UIExtensionAttribute() : base(typeof(IUIExtensionDetails)) 

Вы должны передать тип контракта там, а не тип метаданных:

public UIExtensionAttribute() : base(typeof(IUIExtension)) 

(Кроме того, в чтобы убедиться, что ваш пользовательский класс экспорта имеет правильные свойства, как ожидалось при импорте с метаданными, я бы сделал его реализованным интерфейсом IUIExtensionDetails, но это необязательно.)

+0

+1 Благодарю вас, вы правы. –

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