MEF with interface from class library [Solved]

Topics: Prism v4 - Silverlight 4
May 3, 2011 at 1:01 PM

Dear all,

I created an interface and implementation in the Infrastructure class-library dll marked with Export.

Now I need to load it from another module, I try the Importconstructor but it isn't working. I then tried with [Import] on a property also not working.

What is the best way to load the interface implementation from a class-library from another modules.

Regards

Waleed

May 3, 2011 at 3:22 PM

Hi Waleed,

In order to import your specific class in a module, you need to register your Infrastructure assembly in the container in bootstrapper´s ConfigureAggregateCatalog method.

To do this, you need to add a reference in your Shell project, and in the aforementioned method the code should look like this:

protected override void ConfigureAggregateCatalog()
{
    this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(MyImplementationClass).Assembly));
} 

Additionally, you can retrieve an instance of your class using the ServiceLocator in your modules, like this:

[ExportModule(typeof(MyModule))]
public class MyModule: IModule
{
    private readonly IMyImplementationClass myClass;

    public void Initialize() 
    {
       myClass = ServiceLocator.Current.GetInstance<IMyImplementationClass>();
    }
}

I hope you find this information useful.

Thanks,

Miguel Bronzovic
http://blogs.southworks.net/mbronzovic

May 3, 2011 at 4:25 PM

Hello Miguel,

Exactelly what I did, have alook at my code:

This is the Interface & the implementation class at the class-library

public interface IWindowController

[Export(typeof(IWindowController))]
[PartCreationPolicy(CreationPolicy.Shared)]
public class WindowController : IWindowController

This is how I add the class-library to the cataloge:

 

protected override void ConfigureAggregateCatalog() 
{ 
base.ConfigureAggregateCatalog(); 
this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof (BootStrapper).Assembly));
this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(WindowController).Assembly));
}

 

I do the reference in my VM as follows:

public IWindowController WController { get; set; }

WController = ServiceLocator.Current.GetInstance<IWindowController>();
But the last line (servicelocator) is throwing exception :
"Activation error occured while trying to get instance of type IWindowController, key "" "
What could be the issue here
Appreciate your feedback
Waleed
Developer
May 3, 2011 at 5:00 PM

Hi Waleed,

The problem you're experiencing could be caused by a timing issue. You should make sure that, when you attempt to retrieve the instance of IWindowController from the container, the ConfigureAggregateCatalog method has already been called.

Also, it should be noted that these kind of exception may arise because of multiple causes. For example, if there is an invalid operation that would throw an exception in the WindowController constructor, you might experience an exception like the aforementioned. You should make sure that this is not the case by, for example, removing all the content of the WindowController class and checking if the same exception is thrown.

If you can't find the reason of this unexpected behavior, it would be helpful if you could provide us with more detailed information regarding your scenario.

I hope you find this helpful.

Guido Leandro Maliandi
http://blogs.southworks.net/gmaliandi

May 3, 2011 at 5:11 PM

Hello Guido,

I don't think it is a timing issue as I do my call after the page is loaded and also after calling dataservice class to fecth some data.

I have a breakpoint in my class constructor that never gets hit ... !! how can this be true ..

My scenario is simple:

I have an implementation of a Dialoge in this IWindowControl/WindowControl that I would like to use over my moduels 

Well, I was thinking of extending this scenario to be a strategy of loading my modules dataservice from different class-libraries.

Bets regards

Waleed

May 4, 2011 at 1:39 PM

Waleed,

Since you continue experiencing this issue, it could be helpful if you could provide us with a full repro sample of your solution, so that we can help you to identify the cause of your problem.

You could upload your solution to SkyDrive and post the link here.

Thanks,

Miguel Bronzovic
http://blogs.southworks.net/mbronzovic

 

May 5, 2011 at 1:51 PM

Hello Miguel,

Appreciate your willing to help ...

Here is the link to the repo solution I have created.

Run the application, click Login, press the opendialog button to see the error

Hope you can help me with this ...

Regards,

Waleed

Developer
May 5, 2011 at 2:01 PM

Hi Waleed,

We've checked the link you've posted, but it says that the item might no longer exist or is no longer available. Could your upload it again?

Thanks,

Guido Leandro Maliandi
http://blogs.southworks.net/gmaliandi

May 5, 2011 at 6:50 PM

Sorry Guido,

It is the first time I use skydrivre, can you try again please

Regrads

Waleed

May 6, 2011 at 1:44 PM
Edited May 6, 2011 at 5:23 PM

Okay guys,

I solve it in the repo sample But not in my main application ...

Simply add the IWindowController to the VM as follows:

[Import]
public IWindowController WindowController { get; set; }
Regards
Waleed
I guess I need to do more work there ... 

EDITED:
I even took the sample back to my application & it stoped working ...
I don't know what it could be .. a project settings or what !!

Why the Servicelocator fail to import the Implementation?
Best
May 6, 2011 at 11:54 PM
Edited May 6, 2011 at 11:58 PM

Finally Solved ... !!

Yes, I found the problem, it was that other models was referencing the Infrastructure project has the CopyLocal = true so it was loaded more than once.

I fixed it and now I can use the [Import] or [ImportConstructor] on my VM ... But still don't know why the Servicelocator is not working yet...

Anyway, thanks guys for your help.

Regards

Waleed