I have four Silverlight 4 apps, each in their own Visual Studio project, for which I want to write a "shell" to host them so they appear to the user as a single application. To minimize download times, I will download the XAPs and supporting DLLs dynamically. So I will end up with 5 apps - the shell and the four sub-apps. Now my problem:
My apps all reference the Telerik suite, and this is a fairly significant download. When I build my apps, the Telerik DLLs get zipped into each XAP (as expected). So even if I dynamically load the XAPs, the Telerik DLLs will be downloaded multiple times, once for each XAP.
So how do I make it so the Telerik DLLs are downloaded only once (say, by the Shell), and shared by all the sub-applications?
If you go into the Properties window of your various Silverlight projects, and select the "Silverlight" tab, you'll see an option to "Reduce XAP size by using application library caching". If you select that, the support libraries (Telerik, in this case) will get packaged into separate .zip files that can be downloaded separately. See here for more details, including instructions on how to configure your own assemblies for this sort of behavior. (I presume, though I haven't checked, that Telerik has done this with their controls.)
Related
What I want to do
I've been playing around with the newly released Silverlight 5 and Silverlight 5 Toolkit (December 2011), and I would like to try deploying my 3D Silverlight test application to a third-party hosting server (AppHarbor in my case, but I'm open to other options).
My test application is simply the default Silverlight 3D application that you get when you create a new Silverlight 3D app:
Blog: http://blogs.msdn.com/b/eternalcoding/archive/2011/12/10/silverlight-toolkit-september-2011-for-silverlight-5-what-s-new.aspx
It looks like AppHarbor (and most other hosting sites) require that you copy the required Silverlight 5 DLLs into your project, because they don't have the required SDKs/Toolkits installed on their servers.
Seems fine in theory, but I have no idea how to actually do this with Silverlight.
The problem
The problem is two-fold:
I'm not sure exactly which DLLs need to be manually copied into my project, and I'm not sure how they should be included and referenced.
After some experimentation with copying a few of the Silverlight XNA DLLs into my project and referencing the local project DLLs (instead of the SDK-installed and Toolkit-installed DLLs), the basic 3D Silverlight app now crashes when I run it in the browser -- locally. (The Silverlight plugin crashes.) I didn't have this problem before I started fiddling with the references and DLLs; the default project works just fine. So I haven't even gotten to deploying to a hosting server, because it no longer runs locally.
An aside
On the latter point above (Silverlight plugin crashing), the issue seems to be related to the 3D Silverlight functionality, which apparently requires elevated trust/permissions -- admittedly, I don't fully understand how that all works yet.
Generally speaking -- irrespective of all of this DLL/reference fiddling -- it seems like I need to check "Require elevated trust when running in-browser" in the Silverlight3dApp project properties to get the spinning 3D cube app to show up in the browser. Alternatively, if I leave that unchecked, I need to manually right-click the Silverlight 5 app in the browser and enable 3D graphics on the Permissions tab. (Side note: I'm interested in how this will effect my end-users if I ever do get this deployed. Will they have to manually adjust permissions in the same way? Anyway, that's a question for a different day.)
The point of this aside:
The Silverlight plugin does not crash if I leave everything the way it is by default.
If I copy the Silverlight DLLs into my project and reference them locally, the Silverlight plugin crashes if 3D permissions are enabled.
If I copy the Silverlight DLLs into my project and reference them locally, the Silverlight plugin does not crash if 3D permissions are disabled.
The question
Has anyone successfully deployed that basic Silverlight 5 3D app to a server without Silverlight 5 (and the Silverlight 5 Toolkit) installed?
How did you do it? What files need to be copied into my project and referenced locally? Which references (if any) need to be removed?
Sub-question: If anyone has any insights about the elevated trust/permissions issue, I would love to hear those as well.
For AppHarbor I create a folder in the Silverlight project (lib) and copy all assemblies that I am dependent on and mark all the assemblies with copy to output.
Next I use subst to make a virtual drive that points to this folder and I add all the references to the assemblies on that virtual drive. (This is not needed for AppHarbor but this way I can check out my code to any folder on any machine I want without messing up the paths)
Note that you also need to add these dll's to the repository (git/mercurial) because a standard .hgignore file will skip the *.dll files.
Have you verified you are running the latest runtime for Silverlight? Did you have a previous developer runtime installed? http://www.microsoft.com/getsilverlight/get-started/install/
Hmm... I'm going to go with the above answer. I'm using the latest Silverlight 5 runtime and Silverlight 5 Toolkit and have not had any issues. Here's an app where I'm loading and animating an FBX model in Silverlight (it does require you to right click and set the permissions) and it works fine:
http://www.dustinhorne.com/necodecamp.html
As an aside I'm wrestling with whether to run in elevated trust or force the user to allow 3D acceleration. Personally I hate making the whole app elevated trust just for the 3D stuff from a security standpoint, although if you want to run it out of browser you may want to do that anyway and sign the app with a code signing certificate.
Is it possible to unload a Dll that I previously dynamically loaded into my App?
Background/comments:
1.- We have a requirement that third party developers will implement a wizard-like activity that will be dynamically loaded and executed into our Silverlight application.
2.- We will probably use MEF to put the XAP and Dll catalog into the Silverlight App Domain.
3.- With MEF, its possible to unload the catalog objects, but the Dll will remain loaded into the App Domain.
What we are looking for is to get rid of those Dlls in memory, as the appliance that runs the SL application can remain powered on for long time, and we don't want to pollute its memory with unnecessary Dlls.
Any ideas?
You cant unload a single dll from an appdomain on any version of th clr, the only option for unloading dlls is unloading the entire appdomain.
Unfortunatly you cant create your own appdomains in silverlight as far as i know, but you could always have multiple silverlight apps on the same page.
i wonder though if its a long running app, if its not better to look at desktop .net.. you could use the .xbap deployment format if you still want to run your app in the browser
How does Silverlight application work in browser?
E.g When I access a page having Silverlight control, how does Silverlight runtime extract data/ dlls from 'XAP' package? does it load all dlls in one go or support lazy loading of dlls?
If you're interested in some of the inner working of how the silverlight plugin and how it reads the XAP visit http://stuff.seans.com/2009/03/23/hello-silverlight-world-part-3-the-lifecycle-of-a-silverlight-control/#comment-826
He sums it up very well.
The Silverlight Runtime will extract and load all the DLLs from the Xap file before executing the entry point. Other files within the Xap will be extracted in an on demand fashion.
If you have significant "data" files in your Silverlight project and they need to be in the Xap add them as "Content" rather than as "Resource".
For larger Silverlight apps there are technologies such as MEF which allow you to divide up your app into multiple XAPs and support the dynamic loading of dlls.
Silverlight xap file is just a zip file that contains all required dll s, and files for executing. browser downloads, than extracts files and start executing using Silverlight player, which is light version of .NET engine. Of course there are technologies for lazy loading dll's too, I guess, if you need it.
When you surf a silverlight site, I believe it downloads the site to the client.
Excluding practicality, lets say your going to develop a large full silverlight site with nearly a thousand pages of static content.
Is there any way you can set the compiler to divide the silverlight app in small parts that will only download as a user attempts to access different areas of the huge site?
You need to use Managed Extensibility Framework (MEF) of Silverlight.
With it you can create small silverlight projects and load them when you need.
Here are some links:
3 Steps to MEF - Export, Import, Compose from silverlight.tv
When and Where to use MEF from silverlight.tv
Using MEF with Silverlight 4 for Extensibility from silverlight.net
To be more specific it downloads the XAP file to the client, which is the end product for your silverlight project.
(Input) Silverlight project -> (Output) one XAP File (containing the main assembly and its dependencies) compressed in a normal ZIP file, but ironically renamed to take XAP extension.
Yes, this is doable, see my answer HERE, you need the same methodology depending on the control (portion) you need upon a specified condition.
I'm using MEF with my Silverlight 4 app to dynamically load xap files. To optimize this process, I've removed various assemblies from my xaps since I know they've already been loaded by the base xap. This reduces the size of my dynamically loaded xaps. I accomplished this by setting the "Copy Local" flag for each assembly reference to "false".
This all seems to work fine when I build in Visual Studio 2010 - my xaps are much smaller. However, when the same projects are built by the build server, all the excluded references are once again in the xap file hence tripling the size of the xap.
I've read several blogs/articles regarding similar experiences but no resolution. Very frustrating - any help is appreciated.
Xap files are just Zip files with a different extension. So if you can't figure out why the build server is including the assemblies you don't need, you could create a post-build step that treats the Xap as a Zip and removes those assemblies from it.