locked
Loading parts from unreferenced assembly RRS feed

  • Question

  • Hi,

    This may be a silly question to ask, but I'm new to MEF and struggling a bit on this issue. Hope to find some help here.

    This is what I'm trying to accomplish:

    • I have a main application (say a console app), in which I would like to consume extension assemblies that are not to be referenced by the main app.
    • I have created a separate assembly containing interfaces only (e.g. ILogger, ICacheManager, IMessageSender,... You get the idea). The main app references this assembly.
    • I have a third assembly, which references and implements those interfaces. The idea is that it should be possible to change e.g. the logger implementation (e.g. EntLib-based to log4net-based) without having to recompile the main app. (Recompilation should only be necessary if I add interfaces).

    Now, in my console app, I start with the following code:

    class Program
    {
        static void Main(string[] args)
        {
            Program p = new Program();
            p.Run();
        }
    
        private void Run()
        {
            Compose();
        }
    
        private void Compose()
        {
    
            var catalog = new AggregateCatalog(
                new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly()),
                new DirectoryCatalog("Extensions", "Extension.dll")
                );
    
            var container = new CompositionContainer(catalog);
                           
            container.ComposeParts(this);
    
            // I'd expect to see my parts here.
        }
    }

    I would expect that I would find my exported part in the catalog/container after completing the Compose method. The catalog does find and load the Extensions library.

    For some obscure reason (well, obscure to me), I find no parts.

    Can anyone tell me why this is, and/or what I should do to accomplish my goal?

    What I do find puzzling as well is that, if a add a reference to extension assembly, and add an AssemblyCatalog to my AggregateCatalog, it does work. Like so:

    private void Compose()
    {
    
        var catalog = new AggregateCatalog(
            new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly()),
            new AssemblyCatalog(typeof(Extension.EMailSender).Assembly)
            );
    
        var container = new CompositionContainer(catalog);
                           
        container.ComposeParts(this);
    }

    I think I'm missing something really simple here, but I need a pointer.

    I've posted my sample solution here: http://sdrv.ms/MSKI6f

    Hope to find some help.

    Thanks,

    Fréderic

    Monday, June 25, 2012 7:57 AM

All replies

  • Was hoping I would have gotten some feedback by now... Anybody?
    Friday, August 3, 2012 1:06 PM
  • Catalog is like a source of extension components. You can explicitly say: "here is the assembly. take parts here", or you can say: "here is file system directory, search parts in assemblies there".

    Developer

    Thursday, August 9, 2012 1:35 PM
  • Not sure exactly what you're expecting here.

    In order to use a IMessageSender, you're going to need a reference to the interfaces assembly.

    I ran your sample with slightly modified Compose() method:

                var catalog = new AggregateCatalog(
                    new DirectoryCatalog("Extensions", "Extension.dll")
                    );
    
                var container = new CompositionContainer(catalog);
                           
                var sender = container.GetExportedValue<IMessageSender>();

    And it works fine:  sender is an EmailSender.

    Friday, August 17, 2012 2:07 PM