2011-01-17 4 views
1

Je pense que je perds la tête. :) Cela fait deux jours que je me bats avec ça. Le code a l'air correct. Mais pour une raison quelconque, lorsque j'essaie d'accéder au champ [ImportMany], il est nul, ou au moins ne renvoie aucune valeur.MEF Attributs personnalisés et Lazy

Il obtient les 3 parties du catalogue, mais elles ne sont pas appliquées à l'import Lazy [] que je définis.

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

} 

Répondre

2

Votre attribut de métadonnées est en train de définir les exportations comme typeof(IUIExtensionDetails) qui est votre contrat de métadonnées, et non pas votre extension réelle. Modifiez le constructeur attribut personnalisé à:

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

+ 1 merci, vous avez raison. –

3

Votre erreur est ici:

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

Vous devriez passer le type de contrat là-bas, pas le type de métadonnées:

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

(Aussi, Afin de vous assurer que votre classe d'exportation personnalisée a les bonnes propriétés, comme prévu par l'importation avec des métadonnées, je le ferais implémenter l'interface IUIExtensionDetails, mais ce n'est pas obligatoire.)

+0

+ 1 merci, vous avez raison. –