locked
Problems with nested imports - OnImportsSatisfied is called twice RRS feed

  • Question

  • Hi all,
    I have a problem related to nested imports in MEF.
    I attached a sample to illustrate what is happening.

    in the button1_Click I first import the IImporter list via an Importers class. The OnImportsSatisfied for the imported IExMods is called twice here. Secondly I instanciate the previously imported Importer directly, there the OnImportsSatisfied is only called once...

    Does anybody has a clue what is going on here or might be able to put my head into the right direction?

    Any help is kindly appreciated,
    best regards
    Andy

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.Composition;
    using System.ComponentModel.Composition.Hosting;
    using System.Linq;
    using System.Reflection;
    using System.Text;
    using System.Windows.Forms;
    
    namespace TestRange
    {
        public partial class frmImporterTest : Form
        {
            public frmImporterTest()
            {
                InitializeComponent();
            }
    
    
            private void button1_Click(object sender, EventArgs e)
            {
    
    
                // in this block there is one call to OnImportsSatisfied of Importer
                // and two calls to OnImportsSatisfied of ExtMod (should be only one)
                Importers importers = new Importers();
                List<IImporter> importersList = importers.ImportersList;
    
                foreach (IImporter imp in importersList)
                {
                    List<IExtMod> extMods = imp.ExtMods;
                    int a = 1;
                }
    
                int b = 0;
    
                // in this block there is one call to OnImportsSatisfied of Importer
                // and only one calls to OnImportsSatisfied of ExtMod (should be only one)
                Importer imp2 = new Importer();
                List<IExtMod> extMods2 = imp2.ExtMods;
    
                int c = 0;
            }
        }
    
        public interface IImporter
        {
            List<IExtMod> ExtMods { get; }
        }
    
        public interface IExtMod
        {
            string Name { get; }
        }
    
        public class Importers : MarshalByRefObject, IPartImportsSatisfiedNotification
        {
    
            public bool Loaded { get; protected set; }
    
            public Importers()
            {
                ComposeImporters();
            }
    
    
            private Lazy<IImporter>[] _importerStorage;
            [ImportMany]
            protected Lazy<IImporter>[] ImporterStorage
            {
                get { return _importerStorage; }
                private set { _importerStorage = value; }
            }
    
            public List<IImporter> ImportersList
            {
                get
                {
                    if(ImporterStorage == null)
                    {
                        return new List<IImporter>();
                    }
    
                    return ImporterStorage.Select(s => s.Value).ToList();
                }
            }
            
    
            public void ComposeImporters()
            {
    
                AggregateCatalog catalog = new AggregateCatalog();
                AssemblyCatalog cat = new AssemblyCatalog(this.GetType().Assembly);
                catalog.Catalogs.Add(cat);
    
                CompositionContainer container = new CompositionContainer(catalog);
    
                try
                {
                    container.ComposeParts(this); 
                }
                catch (ReflectionTypeLoadException typeLoadException)
                {
                    StringBuilder sb = new StringBuilder();
    
                    foreach (Exception o in typeLoadException.LoaderExceptions)
                    {
                        sb.AppendLine(String.Format("{0}", o));
                    }
    
                    Console.WriteLine(sb.ToString());
    
                }
                catch (CompositionException compositionException)
                {
                    Console.WriteLine(compositionException.ToString());
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
    
                Loaded = true;
            }
    
            #region Implementation of IPartImportsSatisfiedNotification
    
    
            public void OnImportsSatisfied()
            {
                int i = 0;
            }
    
            #endregion
        }
    
    
        [PartCreationPolicy(CreationPolicy.Shared)]
        [Export(typeof(IImporter))]
        public class Importer : MarshalByRefObject, IImporter, IPartImportsSatisfiedNotification
        {
            
            public bool Loaded { get; protected set; }
    
            public Importer()
            {
                ComposeExMods();
            }
    
    
            private Lazy<IExtMod>[] _exModStorage;
            [ImportMany]
            protected Lazy<IExtMod>[] ExModStorage
            {
                get { return _exModStorage; }
                private set { _exModStorage = value; }
            }
    
            
    
            public void ComposeExMods()
            {
    
                AggregateCatalog catalog = new AggregateCatalog();
                AssemblyCatalog cat = new AssemblyCatalog(this.GetType().Assembly);
                catalog.Catalogs.Add(cat);
    
                CompositionContainer container = new CompositionContainer(catalog);
    
                try
                {
                    container.ComposeParts(this); 
                }
                catch (ReflectionTypeLoadException typeLoadException)
                {
                    StringBuilder sb = new StringBuilder();
    
                    foreach (Exception o in typeLoadException.LoaderExceptions)
                    {
                        sb.AppendLine(String.Format("{0}", o));
                    }
    
                    Console.WriteLine(sb.ToString());
    
                }
                catch (CompositionException compositionException)
                {
                    Console.WriteLine(compositionException.ToString());
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
    
                Loaded = true;
            }
    
            #region Implementation of IPartImportsSatisfiedNotification
    
    
            public void OnImportsSatisfied()
            {
                int i = 0;
            }
    
            #endregion
    
            #region Implementation of IImporter
    
            public List<IExtMod> ExtMods
            {
                get
                {
                    if (ExModStorage == null)
                    {
                        return new List<IExtMod>();
                    }
    
                    return ExModStorage.Select(s => s.Value).ToList();
                }
            }
    
            #endregion
        }
    
        [PartCreationPolicy(CreationPolicy.Shared)]
        [Export(typeof(IExtMod))]
        public class ExtMod : IExtMod
        {
            public ExtMod()
            {
            }
    
            #region Implementation of IExtMod
    
            public string Name
            {
                get { return "Fubar"; }
            }
    
            #endregion
        }
    
    }
    

    Friday, October 12, 2012 9:32 AM