System.Windows.Package and PackageCatalog

Aug 16, 2009 at 11:36 PM
Edited Aug 17, 2009 at 12:14 AM

HI there.

I have recently installed v2010 with silverlight 3 etc. If I create an empty Silverlight 3 (.Net 4) Application
and add the following two lines to the App() constructor, my internet explorer crashes when I run the empty silverlight 3 app.

 
        public App()
{
PackageCatalog catalog = new PackageCatalog(); //added
catalog.AddPackage(Package.Current); //added

this.Startup += this.Application_Startup;
this.Exit += this.Application_Exit;
this.UnhandledException += this.Application_UnhandledException;

InitializeComponent();
}

I have determined that it is specifically the request to Package.Current that causes the failure somehow. Therefore the following code would also crash iexplorer:

        public App()
{
Package foo = Package.Current; //added
this.Startup += this.Application_Startup;
this.Exit += this.Application_Exit;
this.UnhandledException += this.Application_UnhandledException;

InitializeComponent();
}

I need these things to work if I am going to get my catalog fixed up for the CompositionContainer.
I have already gotten this to work on WPF using AssemblyCatalogs and DirectoryCatalogs, but in silverlight
I must use this PackageCatalog that cannot be fed because Package.Current hangs iexplore.

Interestingly if I use WPF tactics to load a catalog, the application does work. By WPF tactics I mean:

AssemblyCatalog catalog = new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly());

_container = new CompositionContainer(catalog);
That code works fine in silverlight 3, but using PackageCatalog does not.

Does anybody else get this? I have basically based my code on a demo posted by this clever dude who presented
ViewModel, IoC and Dependency Injection (using MEF) to us in a seminar at Tech Ed 09 Africa. I have tried to replicate
what he did but oh well... donno why iexplorer crashes like that. His never did and I am sure he has the kind of setup I have.

W

PS- My Setup:

Windows 7RC0 + VS2008 SP1 + Silverlight 3 Tools + Blend 3 RC + VS2010 beta1 +  Silverlight 3 SDK + Silverlight Developer 3 + ME 6 Preview

The Silverlight 3 Application was created in VS2010 with .Net 4 selected ( selecting .Net 3.5 causes the same bahaviour )

Developer
Aug 17, 2009 at 6:23 PM

Thanks for reporting the issue. Are you able to debug the application to see what exception is being reported?

The difference in your two code snippets is Package.Current will load more than just the executing assembly into the catalog it will load all the assemblies that are found in your XAP into the catalog.

There is a good likelihood that the Package API’s will be removed from MEF in a future preview, they were there for experimentation. With that said if the AssemblyCatalog approach works for you it is certainly a more that acceptable approach, especially if you which to share the approach between Silverlight and WPF.

Aug 17, 2009 at 8:10 PM
Edited Aug 17, 2009 at 8:35 PM

Aah yea.

I have more news. I kind of found the problem. It's just difficult for me to determine why my solution works. In short, if you reference Package.Current "to soon" in your Silverlight app, it causes IE to crash later on. (other browsers don’t crash but the content is broken) Where exactly that line of "to soon" is I have yet to determine.


Ok so here goes my long  solution/problem comment, but be warned its terribly technical an context specific. I will try my best to make it understandable. In my original post I referred to a blog that demonstrates a very interesting implementation of an IoC pattern in a Silverlight app. Specifically, NK (the blog guy) tries to avoid as much code behind in his UI's by pretty much binding everything. The one thing he binds to from all his views, is something he calls the "View Model Registry". This viewModelRegistry contains a reference to the IoC container. When I copied/re-implemented this viewModelRegistry concept I made a slight change in my implementation.  I constructed the IoC container inside the viewModelRefistry's constructor, whereas NK implemented a kind of a lazy load singleton pattern property getter for his IoC container. This causes the major difference in that my ViewModelRegistry, and therefore IoC container, gets constructed VERY early in the application startup (The ViewModelRegistry is declared in App.xaml's ResourceDictionary). The IoC container constructs which in turn tries to mojo with those packages and catalogs to early which crashes IE. To answer your earlier question, you cannot really debg the problem. Basically IE crashes when the silverlight has done all its startup and wants to show itself. Hope that makes sense, it does to me :D 

Yea, I agree that Package.Current loads all parts from all assemblies in all XAPs. My framework incidentally does make use of this extra XAP extension trickery. I hope they do not remove the Package API. I would like to play with it some more, but if it cannot be used to make a sensible app then... oh well it was fun.

Where I am getting stuck now is this entire concept of loading XAP's only when they are needed. Currently my naive concept implementation looks something like this:

   	public IocContainer()

        {           
            _packageCatalog = new PackageCatalog();
            _packageCatalog.AddPackage(Package.Current);

            Package.DownloadPackageAsync(new Uri("stampModelLibrary.xap", UriKind.Relative), (e, p) =>

            {
                if (!e.Cancelled && e.Error == null)
                {                   
                    _packageCatalog.AddPackage(p);
                    _partsLoaded = true;
                }
            });
            _container = new CompositionContainer(_packageCatalog);           
        }

This was my first attempt and I quickly realized that it sucks. I have yet to fix it to make it work. I would like to know how someone implemented this behavior properly? What bombs me out is that somehow you have to delay things until the Async Load completes. This creates complexity because the views in your UI do not know their viewModels cannot be created yet because their Dependencies are still loading. Since the viewModels relate to their views by means of binding, the binding will silently fail and result in a stale UI. 

Now I have not really put much thought into avoiding this issue, but maybe someone has already investigated and determined the cleanest implementation. 

I can but hope ;) 

 

 

 

 

Developer
Aug 25, 2009 at 7:40 PM

Sorry for not following up sooner here. I think the problem is that you are accessing the API too soon instead of doing in the App constructor try doing the work in the Application_Startup event and then hopefully the IE crash will go away.

As far as the DownloadPackageAsync call you can do that anytime you wish (after the Application construction) some people do it at a point based on some user interaction, such as a login but it is really up to you when you want to download new packages.