Is SatisfyImportsOnce asynchronous?

Jul 28, 2010 at 4:11 AM

Hi there,

I am just wondering if a call to CompositionContainer.SatisfyImportsOnce is asyncronous or not?  I assume it is because of the existence of the IPartImportsSatisfiedNotification interface and its OnImportSatisfied method.  Does this mean that in order to be sure that execution waits until imports are satisfied I will have to satisfy them each manually with CompositionContainer.GetExportedValue<T>()?

Thanks in advance,

Chris

 

Jul 28, 2010 at 6:50 AM
Edited Jul 28, 2010 at 6:51 AM

How so? Asynch would imply multi-threading and MEF is definitely not multi-threaded. It's not the type of work load that can be efficiently parallelized. However, MEF can be used in multi-threaded environments with the thread-safe constructor overload.

The purpose of IPartImportsSatisfiedNotification is to notify the part after it has had it's imports satisfied. Whenever a part is created by or satisfied by MEF and it implements this interface, MEF will callback into the object and you can preform some kind of initialization code. I have a couple scenarios where I can not use constructor injection or the part satisfies some other import, then, this notification is ideal for that.

Jul 28, 2010 at 7:04 AM

Hmm, ok.  I guess i'm misunderstanding something somewhere.  

I want to perform initialization code like you suggested and for that initialization code I need all the imports of that part to be satisfied.  So the situation I have is that a parameterless constructor on a part which is used by MEF when itself is exported.  That constructor calls the SatisfyImportsOnce method to satisfy its own imports, which is the last line of that constructor.  I then have an OnImportSatisfied method which holds the initialization code.

So my new understanding from your information is that MEF will not satisfy the imports asynchronously but rather perform all the importing on the single SatisfyImportsOnce method call and I instead can put my initialization code immediately after this line, still in the constructor?

Really appreciate your help.  Thanks!

Chris

Jul 29, 2010 at 8:13 AM
Edited Jul 29, 2010 at 8:13 AM

Yes.

I typically rely on this list when choosing what approach to take, in order of preference.

  1. ImportingConstructor (constructor injection)
  2. Import, ImportMany (setter injection)
  3. GetExportedValue
  4. SatisfyImportsOnce

If one is not possible I just move on to the next. I want to avoid having to construct the object myself whenever possible.

The call to SatisfyImportsOnce can originate from anywhere. That it is being called from within the constructor makes it possible to immediately follow up with initialization code but you could also implement IPartImportsSatisfiedNotification and put the initialize code there. That way it doesn't, matter how the imports are satisfied, just that they are satisfied by MEF.

Jul 29, 2010 at 8:40 AM

Excellent explanation, thank you.

I was getting thrown off by the SatisfyImportsOnce method.  I didn't think about it being called from outside of the part whose imports are being satisfied.  It makes sense now and I can use MEF in that way I had hoped.  Long live MEF!