2011-01-17 6 views
1

Ich glaube, ich verliere meine Meinung. :) Ich habe seit zwei Tagen damit zu kämpfen. Der Code sieht richtig aus. Aber aus irgendeinem Grund, wenn ich versuche, auf das Feld [ImportMany] zuzugreifen, ist es null oder gibt zumindest keine Werte zurück.MEF Benutzerdefinierte Attribute und Lazy

Sie erhalten die 3 Teile im Katalog, aber sie werden nicht auf den Lazy [] Import angewendet, den ich definiere.

Hier ist mein Code:

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

} 

Antwort

2

Ihre Metadatenattribute der Exporte als typeof(IUIExtensionDetails) werden definiert, welche Metadaten Vertrag ist, nicht die tatsächliche Erweiterung. Ändern Sie den benutzerdefinierten Attribut Konstruktor:

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

+1 danke, du hast Recht. –

3

Ihr Fehler ist hier:

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

Sie sollten den Vertragstyp es passieren, nicht den Metadatentyp:

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

(auch in Um sicherzustellen, dass Ihre benutzerdefinierte Exportklasse über die richtigen Eigenschaften verfügt, die vom Import mit Metadaten erwartet werden, würde ich die Implementierung der Schnittstelle IUIExtensionDetails veranlassen. Dies ist jedoch nicht obligatorisch.

+0

+1 danke, du hast Recht. –