Partitioned XAP not Reflecting Assembly Updates after Recomposition

May 17, 2010 at 10:45 PM

In the following scenario there appears to be an issue with recomposition. 

Let's say I have an app with two XAP files, Main.XAP and Extensions.XAP.  Main.XAP has a Class which has a property named "Widgets" (As IWidget) marked with ImportMany(AllowRecomposition:=True).  Extensions.XAP is downloaded via the Aggregate/Deployment catalog method and SatisfyImports is called, which populates my property with a collection of IWidget values exported in Extensions.XAP, one of these is "ClockWidget" defined in Extensions.XAP.

Next, I go and modify Extensions.XAP adding a new TextBlock to my "ClockWidget" XAML, which implements IWidget (InheritedExport) and I recompile it.  A directory polling service notices that Extensions.XAP has been modified and proceeds to remove it from the AggregateCatalog on the client, which triggers a recomposition that clears the "Widgets" property.  Then it adds the new version of Extensions.XAP triggering another recomposition, which fills in the "Widgets" property with IWidget implementations (including "ClockWidget") again.

Now, my problem is that when "Widgets" is filled in after Extensions.XAP is updated, the widgets still reflect the old version of Extensions.XAP before it was recompiled/redeployed.  The new TextBlock that was added to "ClockWidget" does not appear on the UI.  If I close the application and re-open without recompiling anything, "ClockWidget" has the new TextBlock.

It would seem that somehow MEF or Silverlight caches the old version of the "ClockWidget" part or the assembly it was a part of and re-uses that when it composes it the second time.  The CompositionContainer and Deployment.Current.Parts both seem to have the correct values through points in the workflow.

Any ideas why the old version of "ClockWidget" would be used instead of the new version?  Is there any way to prevent MEF or Silverlight from caching the old Part/Assembly, or a way to unload it before recomposition is done?

Thanks,

-Nick

 

 

 

There appears to be an issue when using XAP Partitioning and recomposition.

 

May 18, 2010 at 2:31 PM
Edited May 18, 2010 at 2:31 PM

For anyone else who is interested...

There is no way to unload an assembly in Silverlight, or the .Net Framework right now.  People get around this in the Framework by creating a new AppDomain and loading the second version of the assembly there.  Silverlight does not support creating a new AppDomain =/.

You can vote here for Silverlight to support creation of new AppDomains:

http://dotnet.uservoice.com/forums/4325-silverlight-feature-suggestions/suggestions/315642-support-for-application-domains?ref=title

http://forums-silverlight-dit.neudesic.com/forums/p/36867/180340.aspx
http://betaforums.silverlight.net/forums/p/169648/382177.aspx
http://forums.silverlight.net/forums/t/59988.aspx

MEF seems to allow for everything necessary to re-deploy pieces of an app without having to re-start it, but once you have actually loaded the assembly into memory by creating a type your stuck with that version of the assembly until you restart the Silverlight app.  Kind of a bummer.

-Nick

May 18, 2010 at 3:02 PM

A possible workaround for the time being is to change the assembly title each time the assembly's XAP is re-deployed.  This still results in multiple "extra" assemblies being loaded into memory, but the assembly will look new to MEF and Silverlight so the correct objects will be composed. 

-Nick