MEF + ładuje tylko jeden plugin

0

mam dwie dll'ki (wtyczki/pluginy)

namespace MEF_Wtyczka_MessageBoxSender
{
    [Export(typeof(IMessageSender))]
    [PluginMetadata("Default", "1.1.0.0")] 
    public class MessageBoxSender : IMessageSender
    {
      ...
    }
}
namespace MEF_Form
{
    [Export(typeof(IMessageSender))]
    [PluginMetadata("MojaForma", "1.2.0.0")] 
    public partial class formularz : Form, IMessageSender
    {
      ...
    }

}

mam również interfejs opisujący właściwości nazwa/wersja każdej wtyczki

  
    public interface IPluginMetaData
    {
        string Name { get; }
        string Version { get; }
    }

 [MetadataAttribute]
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
    public class PluginMetadataAttribute : ExportAttribute
    {
        public PluginMetadataAttribute(string name, string version)
            : base(typeof(IPluginMetaData))
        {
            Name = name;
            Version = version;
        }

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

Staram się załadować wtyczki :

 [ImportMany(typeof(IMessageSender), AllowRecomposition=false)]
        public Lazy<IMessageSender, IPluginMetaData>[] _loadedIPlugins { get; set; }

private void Compose()
        {
            DirectoryCatalog appDir = new DirectoryCatalog(@".\wtyczki");
            CompositionContainer pluginsLoader;
            pluginsLoader = new CompositionContainer(appDir);
            pluginsLoader.ComposeParts(this);

            MessageBox.Show(appDir.Parts.Count().ToString());
    
        }

Tutaj MessageBox pokazuje : 2. I jest to prawdą, w katalogu są dwie wtyczki (dll'ki).

Następnie chcę wyświetlić informacje o wersji/nazwie danej wtyczki :

 public void Run()
        {
            Compose();
            MessageBox.Show(_loadedIPlugins.Count().ToString()); //msg1
         
            foreach (var element in _loadedIPlugins)
            {
                  MessageBox.Show((string)element.Metadata.Version + "\n" +
                 (string)element.Metadata.Name);
            }

        }

I w tym momencie, messagebox dla _loadedIPlugins pokazuje dla Count : 1
Co robię nie tak ? Dlaczego nie mogę załadować drugiej wtyczki ? :/

Po zmianie Lazy<> na :

public Lazy<IMessageSender, IDictionary<string, object>>[] _loadedIPlugins { get; set; }

ładowane są obydwie wtyczki, jednak nie mogę uzyskać dostępu do metadat poszczególnych wtyczek.

Ponownie proszę o pomoc - jak rozwiązać ten problem ?

0

zmieniłem ładowanie wtyczek na :

[ImportManyAttribute(typeof(IMojInterface))]
  public IList<Lazy<IMojInterface, IPluginMetaData>> wtyczki = new List<Lazy<IMojInterface, IPluginMetaData>>();

wtyczka wygląda następująco :

namespace PluginOne
{
    [Export(typeof(IMojInterface))]
    //[PluginMetadata("Wtyczka 1","1.0.0.0","klasa")]

    public class WtyczkaOne : IMojInterface
    {
       // bool PokazForme(Form rodzic);
     //   bool PokazMsg(string wiadomosc);
        public bool PokazForme(Form rodzic)
        {
            return true;
        }

        public bool PokazMsg(string wiadomosc)
        {
            MessageBox.Show("Wiadomosc z wtyczki 1 " + wiadomosc);
            return true;
        }

    }
}

i teraz staram się sprawdzić ile wtyczek zostało wczytanych ( w katalogu "wtyczki" jest tylko jeden plik)

 AggregateCatalog cat = new AggregateCatalog();
         cat.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
         cat.Catalogs.Add(new DirectoryCatalog(@"wtyczki"));
         CompositionContainer contnr = new CompositionContainer(cat);

         contnr.ComposeParts(this);
         MessageBox.Show(wtyczki.Count().ToString());

Messagebox pokazuje, że zostały wczytane dwie wtyczki :/ To tak jakby brało pod uwagę drugi interfejs, opisujący właściwości wtyczek, i traktowało go jako osobną wtyczkę, czyli :

dla IMojInterface -> widzi jako jedna wtyczka i
dla IPluginMetaData -> widzi jako jedna wtyczka, co w sumie daje dwie wtyczki - tyle tylko, że tak na prawdę jest to cały czas jedna i ta sama DLL'ka.

Jak mogę to filtrować ? Chcę korzystać z interfejsu IPluginMetaData, ze względu na możliwość opisania pluginów, ale gdy tylko go używam pojedyncza wtyczka jest zawsze wczytywana podwójnie.

0

Problemem był interface, a właściwie klasa odpowiedzialna za opis wtyczek.

public PluginMetadataAttribute(string name, string version)
            : base(typeof(IPluginMetaData))

po usunięciu :

base(typeof(IPluginMetaData))

program normalnie wczytuje tyle wtyczek ile jest w katalogu

Odnośnie filtrowania wtyczek, można użyć właśnie meta tagów lub

http://blogs.microsoft.co.il/blogs/bnaya/archive/2010/01/20/mef-for-beginner-metadata-part-8.aspx

1 użytkowników online, w tym zalogowanych: 0, gości: 1