views:

43

answers:

3

Hi all,

My question title sounds a little bit difficult - sorry. I'm new in MEF :-).

My scenario:

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
{

}

In the generic list of test, I should have all possible ITest objects with the associated IParameter object. Unfortunately, there aren't any items in the generic list.

Can you help? What did I do wrong?

Thanks in advance.

Regards, pro

//Edit

So I have a compilable Class for my problem :

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; }
    }
}

What do I do wrong? Please help me :-)

Regards, patrick

A: 

Are you exporting IParameter anywhere? In the code you posted, you are not, and this is why the Birthday test isn't being picked up.

Daniel Plaisted
Yes he is ! scroll down the code all the way - the class `BirthdayJobParameter` clearly exports `IParameter`
marc_s
@marc_s Oops, I must have missed the scroll bar! :)
Daniel Plaisted
+1  A: 

Taking a wild guess, it is possibly the working directory of your DirectoryCatalog (depending on how you run the app.)

To verify that this is the problem, replace:

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

With either:

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

or:

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

Cheers, Nick

Nicholas Blumhardt
Thank you for your answer, but the current directory (@"./") is right. I've verified that with the debugger. After the ComposeParts() call,all assemblies are correct loaded and all parts are corrected listed...
pro
You're welcome - I'm out of ideas though. If you can post a complete (compilable) example I can take a look.
Nicholas Blumhardt
+1  A: 

I've found the solution. In the export class of the foo class should be a reference of the derived interface. The constructor which have the importingconstructor flag should have also a reference to the 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; }
    }
pro