Reputation: 1729
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
Upvotes: 1
Views: 5337
Reputation: 31777
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);
Upvotes: 1
Reputation: 36
The point is that if you use a contract (in your case "BirthdayJob") in your export, you need to specify that in your import as well. Like so:
[Export("BirthdayJob",typeof(ITest))]
public partial class BirthdayTest : ITest
{
// class definition
}
And your import:
public class MainClass
{
[ImportMany("BirthdayJob",typeof(ITest))]
private List<ITest> Tests { get; set; }
// class definition
}
The great thing about contracts is that they allow you to group instances of certain objects of a specific type and filter out any unwanted instances of objects of a specific type.
MEF is the coolest!
[Export("PeopleLivingInEdmontonAlbertaCanada",typeof(IPerson))]
public Person KevinParkinson { get; set; }
Upvotes: 2
Reputation: 1729
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; }
}
Upvotes: 1
Reputation: 16744
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.
Upvotes: 0