2010-09-06 3 views
1

Mon titre de la question semble un peu difficile - désolé. Je suis nouveau à MEF :-).MEF: Comment puis-je importer une classe qui a un constructeur marqué avec le ImportingConstructorFlag

Mon scénario:

public class MainClass 
{ 
    [ImportMany(typeof(ITest))] 
    private List<ITest> Tests { get; set; } 

    public MainClass() 
    { 
    Init(); 
    } 

    private void Init() 
    { 
    DirectoryCatalog catalog = new DirectoryCatalog(@"./"); 
    CompositionContainer container = new CompositionContainer(catalog); 
    container.ComposeParts(this); 
    } 
} 



[Export("BirthdayJob")] 
[Export(typeof(ITest))] 
public partial class BirthdayTest : ITest 
{ 
    [ImportingConstructor] 
    public BirthdayUserControl(IParameter parameter) 
    { 
    InitializeComponent(); 
    this.Parameter = jobParameter; 
    } 

    public IParameter Parameter { get; set; } 
} 

[Export(typeof(IParameter))] 
[Export("BirthdayParameter")] 
public class BirthdayJobParameter : IParameter 
{ 
    public override string ToString() 
    { 
     return "Birthday Remember"; 
    } 
} 


public interface IParameter : IMefInterface 
{ 

} 

public interface IMefInterface 
{ 

} 

Dans la liste générique de test, je devrais avoir tous les objets possibles iTest avec l'objet iParamètre associé. Malheureusement, il n'y a aucun élément dans la liste générique.

Pouvez-vous m'aider? Qu'ai-je fait de mal?

Merci d'avance.

Cordialement, pro

// Modifier

J'ai une classe compilable pour mon problème:

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

namespace ObjectContracts 
{ 
    public class Program 
    { 
     static void Main(string[] args) 
     { 
      var container = new CompositionContainer(new TypeCatalog(typeof (IFoo), typeof (Bar), typeof(Foo))); 
      var bar = container.GetExportedValue<Bar>(); 
      Console.WriteLine(bar.Foo.Message); 
      Console.ReadLine(); 

     } 

    } 

    [InheritedExport] 
    public interface IFoo 
    { 
     string Message { get; set; } 
    } 

    [Export] 
    public class Bar 
    { 
     [ImportingConstructor] 
     public Bar([Import("Foo")]IFoo foo) 
     { 
      this.Foo = foo; 
     } 

     public IFoo Foo { get; set;} 
    } 

    [Export("Foo")] 
    public class Foo : IFoo 
    { 
     public Foo() 
     { 
      Message = ":-)"; 
     } 
     public string Message { get; set; } 
    } 
} 

Que dois-je fait de mal? S'il vous plaît aidez-moi :-)

Cordialement, Patrick

+0

Qu'est-ce que vous obtenez? Si quelque chose .... Connaissez-vous l'outil d'analyse de composition de MEFX (http://msdn.microsoft.com/en-us/library/ff576068.aspx) qui peut vous aider à dépanner de tels cas? –

+0

Merci pour votre aide.Mais toutes les pièces sont correctement chargées. Seulement la propriété ne sera pas injectée correctement ... :-( – bitsmuggler

Répondre

2

Le point est que si vous utilisez un contrat (dans votre cas « BirthdayJob ») dans votre exportation, vous devez préciser que dans votre importation ainsi. Comme si:

[Export("BirthdayJob",typeof(ITest))] 
public partial class BirthdayTest : ITest 
{ 
    // class definition 
} 

Et votre importation:

public class MainClass 
{ 
    [ImportMany("BirthdayJob",typeof(ITest))] 
    private List<ITest> Tests { get; set; } 

    // class definition 
} 

La grande chose au sujet des contrats est qu'ils vous permettent aux instances de groupe de certains objets d'un type spécifique et filtrer tous les cas indésirables d'objets de un type spécifique.

MEF est le plus cool!

[Export("PeopleLivingInEdmontonAlbertaCanada",typeof(IPerson))] 
public Person KevinParkinson { get; set; } 
0

Exportez-vous iParamètre partout? Dans le code que vous avez posté, vous n'êtes pas, et c'est pourquoi le test d'anniversaire n'est pas repris.

+0

Oui il est! Faites défiler le code tout le chemin - la classe 'BirthdayJobParameter' exporte clairement' IParameter' –

+0

@marc_s Oups, je dois avoir manqué la barre de défilement ! :) –

1

Prendre une conjecture sauvage, il est peut-être le répertoire de travail de votre DirectoryCatalog (selon la façon dont vous exécutez l'application.)

Pour vérifier que cela est le problème, remplacez:

DirectoryCatalog catalog = new DirectoryCatalog(@"./"); 

Avec soit:

DirectoryCatalog catalog = new DirectoryCatalog(@"<full path to directory>"); 

ou:

AssemblyCatalog catalog = new AssemblyCatalog(typeof(BirthdayTest).Assembly); 
+0

Merci pour votre réponse, mais le répertoire actuel (@ "./") est correct. J'ai vérifié cela avec le débogueur. Après l'appel de ComposeParts(), tous les assemblys sont correctement chargés et toutes les pièces sont corrigées. – bitsmuggler

+0

De rien, je n'ai plus d'idées. Si vous pouvez poster un exemple complet (compilable), je peux jeter un oeil. –

1

J'ai trouvé la solution. Dans la classe d'exportation de la classe foo devrait être une référence de l'interface dérivée. Le constructeur qui possède l'indicateur importingconstructor doit également avoir une référence à l'interface.

[Export] 
    public class Bar 
    { 
     [ImportingConstructor] 
     public Bar([Import("Foo", typeof(IFoo))]IFoo foo) 
     //public Bar([Import(typeof(IFoo))]IFoo foo) 
     { 
      this.Foo = foo; 
     } 

     public IFoo Foo { get; set;} 
    } 

    [Export("Foo", typeof(IFoo))] 
    public class Foo : IFoo 
    { 
     public Foo() 
     { 
      Message = ":-)"; 
     } 
     public string Message { get; set; } 
    } 
Questions connexes