ComposeParts + Import

Jul 30, 2009 at 7:45 AM

I try to use MEF in an ordinary ASP.NET application (found no sample for this topic) and I have problems.

I call container.ComposeParts(this.Page), the Page is marked with [Export] and then I have another class that imports the same Page.
It looks like the MEF is creating the Page once again on the import even though my dev intuition :) tells me it should use the part I provided.
What am I doing wrong? Please, do not tell me that I should not compose Page as I try to understand how the MEF works so this is not the final approach.

Thanks,

Marcin Celej |.NET Solutions Architect :: Microsoft MVP :: Leader of KGD.NET UG :: Conference Speaker

Jul 30, 2009 at 8:33 AM

Are you saying that during the composition of the Page itself, someone wants to import it?

Glenn

From: MarcinCelej [mailto:notifications@codeplex.com]
Sent: Thursday, July 30, 2009 12:45 AM
To: Glenn Block
Subject: ComposeParts + Import [MEF:63967]

From: MarcinCelej

I try to use MEF in an ordinary ASP.NET application (found no sample for this topic) and I have problems.

I call container.ComposeParts(this.Page), the Page is marked with [Export] and then I have another class that imports the same Page.
It looks like the MEF is creating the Page once again on the import even though my dev intuition :) tells me it should use the part I provided.
What am I doing wrong? Please, do not tell me that I should not compose Page as I try to understand how the MEF works so this is not the final approach.

Thanks,

Marcin Celej |.NET Solutions Architect :: Microsoft MVP :: Leader of KGD.NET UG :: Conference Speaker

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

Jul 30, 2009 at 8:44 AM

Hi Glen,

Yes, that's right. Here goes the simplified version of what I have:

[Export] class MyPage {

[Import] MyPresenter Presenter {get;set;}

OnInit(){ container.ComposeParts(this); }

}

[Export] public class MyPresenter {

[Import] MyPage Page {get;set;}

}

Here is simplified version of what I have. The above sample is created from my memory, not copied.
I just started using MEF so I may make mistakes. My sample is much more complex than what I wrote here so maybe I will need to simplify it to make it working.
Maybe I need Lazy<MyPage> Page ?

BTW: I've met you in Kraków (Poland) on the User Group meeting :).

Marcin

Jul 30, 2009 at 8:54 AM

Yes, this looks like a re-entrancy problem. You are importing the Page, while the Page itself is being composed. I don’t believe this is something we support, though I will look into it. I can suggest two alternative approaches.

1. The simplest way to handle this would be put a method on a presenter like InitializeView which accepts a View and then call that in the setter of the Presenter on the View. This is a very common way to approach MVP and the style we used in patterns and practices with our Web Client Software Factory.

2. An alternative approach which will work is to change the import of the Page on the presenter to be Lazy<MyPage>. Then you will access the .Value parameter to get to the actual Page. This will not suffer from any re-entrancy issues.

Just out of curiosity are you creating a page-level container with each request?

Cool, that was a blast! Glad to hear from you.

Glenn

From: MarcinCelej [mailto:notifications@codeplex.com]
Sent: Thursday, July 30, 2009 1:45 AM
To: Glenn Block
Subject: Re: ComposeParts + Import [MEF:63967]

From: MarcinCelej

Hi Glen,

Yes, that's right. Here goes the simplified version of what I have:

[Export] class MyPage {

[Import] MyPresenter Presenter {get;set;}

OnInit(){ container.ComposeParts(this); }

}

[Export] public class MyPresenter {

[Import] MyPage Page {get;set;}

}

Here is simplified version of what I have. The above sample is created from my memory, not copied.
I just started using MEF so I may make mistakes. My sample is much more complex than what I wrote here so maybe I will need to simplify it to make it working.
Maybe I need Lazy<MyPage> Page ?

BTW: I've met you in Kraków (Poland) on the User Group meeting :).

Marcin

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

Jul 30, 2009 at 9:07 AM

I've just tried the Lazy<> and it didn't help. I will look deeper into it later. I already had the Init method on the presenter and I try to get rid of it (just for fun).

I just started playing with the MEF but my plan is to create Application level container, Session level (child container) and the last one Request (or Page) container. I haven't try that yet, so I do not know if it will work. When I am done with the sample I will publish that so everyone can see how it can be achieved. Moreover: community will find all my mistakes :) which is good for my little, home made project.

Marcin

Jul 30, 2009 at 3:10 PM

It seems on first glance to me that you should exclude MyPage from your catalog. You should also create a container per web request, otherwise only one (shared) page will be used to satisfy all imports.

A more straightforward approach would be to remove the Export attribute on MyPage, and have the OnInit method set the Presenter’s reference to the page explicitly, e.g.:

class MyPage {

[Import] MyPresenter Presenter {get;set;}

OnInit(){

 container.ComposeParts(this);

 Presenter.Page = this;

}

}

[Export] public class MyPresenter {

[Import] MyPage Page {get;set;}

}

Keep a close eye on creation policy – container-per-web-request is the best way to go, having the effect of changing the meaning of CreationPolicy.Shared (the default) to per-web-request.

You can find out more about creation policy here: http://mef.codeplex.com/Wiki/View.aspx?title=Parts%20Lifetime&referringTitle=Home.

Hope this helps,

Nick

Nick

From: MarcinCelej [mailto:notifications@codeplex.com]
Sent: Thursday, July 30, 2009 2:08 AM
To: Nicholas Blumhardt
Subject: Re: ComposeParts + Import [MEF:63967]

From: MarcinCelej

I've just tried the Lazy<> and it didn't help. I will look deeper into it later. I already had the Init method on the presenter and I try to get rid of it (just for fun).

I just started playing with the MEF but my plan is to create Application level container, Session level (child container) and the last one Request (or Page) container. I haven't try that yet, so I do not know if it will work. When I am done with the sample I will publish that so everyone can see how it can be achieved. Moreover: community will find all my mistakes :) which is good for my little, home made project.

Marcin

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

Jul 30, 2009 at 7:39 PM

Thanks for the tips. I already created page / request container. The container is a child one to an Apllication level container.

You are right that pages / user controls should not be exported.

I've already read everything on the wiki here and it was helpful, but the real knowledge comes from development research.

I am not developing to much recently so to play with MEF is a huge fun for me :). I am smiling all day today after my first pains :).

Marcin