Attributs personnalisés et MEF Lazy
-
11-10-2019 - |
Question
Je pense que je perds mon esprit. :) J'ai été aux prises avec ce depuis deux jours. Le code semble bon. Mais pour une raison quelconque lorsque je tente d'accéder au champ [ImportMany], elle est nulle, ou du moins pas retourner toutes les valeurs.
obtenir les 3 parties dans le catalogue, mais ils ne sont pas appliqués à l'importation Lazy [] Je suis en train de définir.
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();
}
}
}
La solution
Votre attribut de métadonnées définit les exportations comme typeof(IUIExtensionDetails)
qui est votre contrat de métadonnées, pas votre véritable poste. Modifiez le constructeur d'attribut personnalisé à:
public UIExtensionAttribute() : base(typeof(IUIExtension)) { }
Autres conseils
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 des métadonnées, je RENDRAIT implémenter l'interface IUIExtensionDetails
. Mais ce n'est pas obligatoire.)