This project has moved and is read-only. For the latest updates, please go here.

Problems expanding the BookLibrary Sample

Jul 2, 2012 at 2:36 PM

Hi, I'm trying to learn WAF by experimenting with the BookLibrary Sample. My first goal was to expand the BookLibraryModel with a new entity "SuperHero" (without any association with the existing entities (tables) in the database) and present the rows of this entity (table) in a new tab.

I've got everything wired up and working except for the controller, where I get an MEF error: 

The composition produced a single composition error. The root cause is provided below. 1)

No valid exports were found that match the constraint '((exportDefinition.ContractName == "Waf.BookLibrary.Library.Applications.Controllers.SuperHeroController") AndAlso (exportDefinition.Metadata.ContainsKey("ExportTypeIdentity") AndAlso "Waf.BookLibrary.Library.Applications.Controllers.SuperHeroController".Equals(exportDefinition.Metadata.get_Item("ExportTypeIdentity"))))', invalid exports may have been rejected.

Resulting in: Cannot set import 'Waf.BookLibrary.Library.Applications.Controllers.ModuleController..ctor (Parameter="superHeroController", ContractName="Waf.BookLibrary.Library.Applications.Controllers.SuperHeroController")' on part 'Waf.BookLibrary.Library.Applications.Controllers.ModuleController'.Element: Waf.BookLibrary.Library.Applications.Controllers.ModuleController..ctor (Parameter="superHeroController", ContractName="Waf.BookLibrary.Library.Applications.Controllers.SuperHeroController") -->  Waf.BookLibrary.Library.Applications.Controllers.ModuleController -->  AssemblyCatalog (Assembly="Waf.BookLibrary.Library.Applications, Version=2.5.0.5, Culture=neutral, PublicKeyToken=null")

 

For the SuperHeroController.cs file I've basically copied the contents of PersonController, and removed the EmailService.

The constructor looks like this: 

 [ImportingConstructor]       

public SuperHeroController(CompositionContainer container, IMessageService messageService, IShellService shellService, IEntityService entityService, SuperHeroViewModel superHeroViewModel)

Ive observed that if I remove superHeroViewModel from the Contstructor the code runs fine.. 

I'm new to WAF and MEF, so there's probably a really simple explenation..


Jul 8, 2012 at 3:48 PM

Maybe this discussion post helps you: Invalid exports - EXCEPTION

Jul 10, 2012 at 11:16 AM

Thanks, that clarified a bit. I solved the issue by starting from scratch again with the BookLibrary sample. Not sure what caused the MEF error, but now it's all good anyway.

Jul 17, 2012 at 5:16 PM

Okay, now I have the problem again. It occurs if I try to modify the BookLibrarySample. Can anyone tell me why I get this strange MEF error? I believe my exports/imports are corrects

Here are the steps I follow.

1. Open BookLibrarySample (unmodified), compile and run to see that everything is okay. So far so good.

2. Open ModuleController.cs,

1. add "private readonly TestController testController;" to the list of private variables

2. modify the [ImportingConstructor] to also include TestController, like this: 

       [ImportingConstructor]       public ModuleController(IMessageService messageService, IPresentationService presentationService,             IEntityController entityController, BookController bookController, PersonController, personController, ShellService shellService, ShellViewModel shellViewModel, TestController testController)        {

3. add a "this.testController = testController;" statement in the constructor body.

 

4. Add a Class to Waf.BookLibrary.Library.Applications.Controllers that looks like this:

using System.ComponentModel.Composition;

namespace Waf.BookLibrary.Library.Applications.Controllers{

    [Export]

    internal class TestController    {

private string test;

        [ImportingConstructor]

        public TracerSystemController(string test){

            this.test = test; 

      }   

   }

}

 

This results in a MEF error:

 

No valid exports were found that match the constraint '((exportDefinition.ContractName == "Waf.BookLibrary.Library.Applications.Controllers.TestController") AndAlso (exportDefinition.Metadata.ContainsKey("ExportTypeIdentity") AndAlso "Waf.BookLibrary.Library.Applications.Controllers.TestController".Equals(exportDefinition.Metadata.get_Item("ExportTypeIdentity"))))', invalid exports may have been rejected.
Resulting in: Cannot set import 'Waf.BookLibrary.Library.Applications.Controllers.ModuleController..ctor (Parameter="testController", ContractName="Waf.BookLibrary.Library.Applications.Controllers.TestController")' on part 'Waf.BookLibrary.Library.Applications.Controllers.ModuleController'.Element: Waf.BookLibrary.Library.Applications.Controllers.ModuleController..ctor (Parameter="testSystemController", ContractName="Waf.BookLibrary.Library.Applications.Controllers.TestController") -->  Waf.BookLibrary.Library.Applications.Controllers.ModuleController -->  AssemblyCatalog (Assembly="Waf.BookLibrary.Library.Applications, Version=2.5.0.5, Culture=neutral, PublicKeyToken=null")

 

Why? 

Jul 21, 2012 at 3:12 PM

I see two issues in your sample code:

  • The class name TestController doesn't match with the constructor name TracerSystemController
  • What should MEF pass for 'string test' parameter in the constructor?
[Export]
internal class TracerSystemController    
{
    [ImportingConstructor]
    public TracerSystemController(string test)
    {
        ...

MEF is responsible to create the "Exported" classes. But in your case it doesn't know what to use for a value for string test - null, string.Empty or something else?Unfortunately, the error messages of MEF aren't often that helpful.

I would do it this way:

[Export]
internal class TracerSystemController    
{
    [ImportingConstructor]
    public TracerSystemController()
    {
        ...
    }

    public string Test { get; set; }

    public void Initialize()
    {
        ...

The controller responsible for the lifecycle of TracerSystemController (the one that calls Initialize, Run and/or Shutdown, e.g. ModuleController) sets the property Test before it calls the Initialize method. This way we know that during Initialize all properties are set.