DeploymentCatalog and different version of referenced assemblies in Xap

Apr 29, 2010 at 12:55 PM

Hi,

I've already posted this to Microsoft Silverlight forum but I just noticed that this could be better place to get answers :)

I have done an test application using MEF and DeploymentCatalog. My purpose was to test if I can create a main application that composes and displays several independently developed applications. Applications are distributed in xap-files and loaded with DeploymentCatalog. Every application exports its user interface to main application with MEF. Applications should not know anything about each other. All communication between applications, if any, is done by using CompositePresentationEvents. Applications are possibly using different versions of third party components.

 Composer implementation in portal looks like this:

       public void Compose()
{
var catalog = new AggregateCatalog();
AddLocalPackageToCatalog(catalog);
AddExternalPackagesToCatalog(catalog);

var container = new CompositionContainer(catalog);
container.ComposeParts(this);
}

private void AddLocalPackageToCatalog(AggregateCatalog catalog)
{
catalog.Catalogs.Add(new DeploymentCatalog());
}

private static void AddExternalPackagesToCatalog(AggregateCatalog catalog)
{
DownloadPackageToCatalog(catalog, "/Plugins/ExternalApplication.xap");
DownloadPackageToCatalog(catalog, "/Plugins/ExternalApplication2.xap");
}

private static void DownloadPackageToCatalog(AggregateCatalog catalog, string uri)
{
DeploymentCatalog deploymentCatalog = new DeploymentCatalog(uri);
deploymentCatalog.DownloadAsync();
deploymentCatalog.DownloadCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(deploymentCatalog_DownloadCompleted);
catalog.Catalogs.Add(deploymentCatalog);
}

static void deploymentCatalog_DownloadCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
if (e.Error != null)
{
throw e.Error;
}
}

Everything works fine if composed applications are using the same version of referenced assemblies. When applications use different version of the same assembly (and that assembly is in xap-files) I get the following exception when the second xap is loaded. Exception is thrown before the DownloadCompleted-event is raised:

 System.IO.FileLoadException occurred
  Message=Could not load file or assembly 'ExternalLibrary, Version=1.1.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The requested assembly version conflicts with what is already bound in the app domain or specified in the manifest. (Exception from HRESULT: 0x80131053)
  StackTrace:
       kohteessa System.Reflection.RuntimeAssembly.nLoadImage(Byte[] rawAssembly, Byte[] rawSymbolStore, Evidence evidence, StackCrawlMark& stackMark, Boolean fIntrospection, SecurityContextSource securityContextSource)
       kohteessa System.Reflection.Assembly.Load(Byte[] rawAssembly)
  InnerException:

That ExternalLibrary is actually a Silverlight Class Library I've made myself for test purposes. It simulates third party component. Both xap files (ExternalApplication.xap and ExternalApplication2.xap) contain different version of ExternalLibrary (1.0.0.0 and 1.1.0.0). I have also modified an API between versions. It seems that xap files cannot contain different version of same assembly if you use DeploymentCatalog.

I've also tried to remove the first DeploymentCatalog from CompositionContainer and dispose it before loading the other xap, but I still receive the same exception. I've also removed the CompositionContainer so that application just loads those xap files without composition. Still the same exception.

Is there any way to remove all assemblies loaded earlier with DeploymentCatalog before loading the second xap? Some other ideas how to solve this problem? I think it is quite annoying limitation in otherwise great system.

 

Best regards,

 Lasse

Developer
Apr 29, 2010 at 3:47 PM

Unfortunately this is a limitation in the current Silverlight runtime. You cannot load too different versions of the same assembly nor can you unload an already loaded assembly. There aren't any workarounds that I'm aware of.

Apr 29, 2010 at 5:21 PM
Thanks for your reply. It's good to know about that limitation.
Jun 10, 2011 at 7:11 PM

I am running into this issue since the Silverlight application I am designing will need to be able to be backwards compatible with plugins that use various older + newer versions of assemblies in the same silverlight app domain.

So to confirm, 1 year later after the last reply to this post, MEF is not the problem, its just that the Silverlight runtime cannot load two differenct versions of the same assembly at the same time, even if all my assemblies have strong name signing?

I thought one of the grand points of using silverlight and MEF was to do plugin based applications, and this is certainly a issue that must be solved. Are there any workarounds that people have figured out yet?

I been trying to get this to work for a number of hours, doing random searches, but this is the only post I found that seems to suggest its impossible.