Mef passing parameters to module

Jun 4, 2010 at 12:01 PM

Hi, I'm studying MEF and I'm not able to resolve a problem.

I have a main application, called MainMEF, and a simple module, called SimpleModule. This one consists of a single UserControl which is loaded dinamically.

When MainMEF starts up, I would be able to pass to the module a reference to main application contained into MainMEF.

I've followed the tutorial by Glenn Block "Building Hello MEF – Part IV – DeploymentCatalog". If is possible I would start from here and add the fix to the above problem.

Thanks in advance.

Developer
Jun 4, 2010 at 5:39 PM

You cannot directly pass data to other modules, the way to do it is to Export the values you want passed and have the module that needs the values import them.

 

Jun 4, 2010 at 6:12 PM

Could you provide a sample starting from Glenn Block "Building Hello MEF – Part IV – DeploymentCatalog"? Thanks in advance

Jun 4, 2010 at 7:50 PM

One approach is to build a specific service for passing the data that you want. An alternative is to utilize a generic message passing service to do thos. You may want to look at Prism’s EventAggregator or Laurent Bugnion’s MVVM Light Messenger classes. Both allow sending pub/sub type messages which can be used to communicate across modules. Here’s a post on how to use EventAggregator with MEF: http://codebetter.com/blogs/glenn.block/archive/2009/02/23/event-aggregation-with-mef-with-and-without-eventaggregator.aspx

With either of these approaches you can tailor a specific message for a particular module which anyone can fire through importing the messenger/event aggregator.

Glenn

From: loller [mailto:notifications@codeplex.com]
Sent: Friday, June 04, 2010 10:12 AM
To: Glenn Block
Subject: Re: Mef passing parameters to module [MEF:214968]

From: loller

Could you provide a sample starting from Glenn Block "Building Hello MEF – Part IV – DeploymentCatalog"? Thanks in advance

Read the full discussion online.

To add a post to this discussion, reply to this email (MEF@discussions.codeplex.com)

To start a new discussion for this project, email MEF@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

Jun 5, 2010 at 12:17 PM
Thank you for your reply Glenn. I'll try this solution. In the meantime, I've tried an other solution and it works. The solution uses CompositionContainer class and ComposeExportedValue method. Then, SimpleModule class uses ImportingConstructor directive. I don't know if there a better way to do this. Thanks again for your support. Mef rocks!!
Jun 5, 2010 at 6:11 PM
You can certainly add values directly to the container while configuring it. The advantage of something like EventAgg or a service is the ability to communicate 'Events' that occur in the app which modules need to know about.

Rather than going to the add to container route you could also export a part into the container like IModuleConfiguration which exposes props to get to the config. Advantage of that you do not have to manually configure the container thus the config part is just discovered like any other part.

Here are two posts on approaches to doing is:


http://codebetter.com/blogs/glenn.block/archive/2010/01/31/exporting-dynamically-changing-configuration-values.aspx

Good luck and glad you like MEF.



Sent from my IPad.

On Jun 5, 2010, at 4:18 AM, "loller" <notifications@codeplex.com> wrote:

From: loller

Thank you for your reply Glenn. I'll try this solution. In the meantime, I've tried an other solution and it works. The solution uses CompositionContainer class and ComposeExportedValue method. Then, SimpleModule class uses ImportingConstructor directive. I don't know if there a better way to do this. Thanks again for your support. Mef rocks!!
Jun 7, 2010 at 3:04 PM
Edited Jun 8, 2010 at 3:29 PM

Hi Glenn, thanks for the reply.

1) Does the EventAggregator solution use the Prism library? If I would use it, do I have to import PRISM dlls?

2) "Rather than going to the add to container route you could also export a part into the container like IModuleConfiguration which exposes props to get to the config. Advantage of that you do not have to manually configure the container thus the config part is just discovered like any other part."

I've read your post (http://codebetter.com/blogs/glenn.block/archive/2010/01/27/how-do-i-expose-configuration-information-through-mef.aspx) but I'm not able to configure it properly. I'll try to explain my needs.


The main application does the following:

private void Application_Startup(object sender, StartupEventArgs e)
{
InitializeModule();
this.RootVisual = new MainPage();
}

private void InitializeModule()
{
AggregateCatalog aggregateCatalog = new AggregateCatalog();
aggregateCatalog.Catalogs.Add(CreateDeployementCatalog("MEFModule.xap")); <-- CreateDeployementCatalog returns a DeployementCatalog

CompositionContainer container = new CompositionContainer(aggregateCatalog);
CompositionHost.Initialize(container);
}

In this snippet of code, as already mentioned, I've also tried to use ComposeExportedValue method. It seems to work but, since I've not fully understood MEF (I'm a newbie), I can't find the right way. Using ComposeExportedValue, the code becomes:

CompositionContainer container = new CompositionContainer(aggregateCatalog);
container.ComposeExportedValue("App.APPlication", App.Current);
container.ComposeParts(this); <-- I can't understand what this call does. With and without this call the solution works.
CompositionHost.Initialize(container);

In this case the module constructor becomes the following:

[ImportingConstructor]
public MEFModulePage([Import("App.APPlication")] Application app) <-- I have a reference from the main application. Not quite elegant but works!!
{
InitializeComponent();
}


The main page does the following:

[Import(AllowDefault=true, AllowRecomposition=true)]
public IPlugin MefPlugin { get; set; }

public MainPage()
{
InitializeComponent();
CompositionInitializer.SatisfyImports(this);
}

public void OnImportsSatisfied()
{
if (MefPlugin != null)
{
LayoutRoot.Children.Add(MefPlugin as UIElement);
}
}


The simple module does the following:

[Export(typeof(IPlugin))]
[PartCreationPolicy(CreationPolicy.Shared)]
public partial class MEFModulePage : UserControl, IPlugin
{
public MEFModulePage()
{
InitializeComponent();
}
}


To summarize, I would be able to pass a reference of the main application to the simple module using 2) solution (http://codebetter.com/blogs/glenn.block/archive/2010/01/27/how-do-i-expose-configuration-information-through-mef.aspx). But I don't know to do that. Could you suggest me the right way to create such a class for the configuration where i colud pass an application reference? I'm think that the 1) solution (EventAggregator one) requires the understanding of PRISM and is more difficult. Isn't true? At the same time, I know that 2) solution isn't a loosely coupled way solution and so isn't elegant.

Thank  you in advance. Best Regards. Lorenzo.