I hear you. There is more guidance for this in the Silverlight space than WPF. If you are going to have an application where connectivity is guaranteed, or you can handle the 25 mb local storage limit for the occasionally disconnected app, then
I highly recommend Silverlight.
If you building a real world LOB app, where connectivity is poor at best or you need access to local
system resources, then there are a few things you can do with you ClickOnce WPF solution (Silverlight 4 will give you access to
programmatic printing support, programmatic access to the clipboard, rich text editing, support for mouse wheel input, local file system access, and out-of-browser execution).
The easiest is to just add a reference to your “unit” projects to the main project. Or you can add something like the following to the Post Build event in your unit projects.
xcopy "$(TargetDir)*.*" "$(SolutionDir)Main\bin\$(ConfigurationName)\Units\" /Y
Add the Units directory to your Main project, but don’t add the assemblies to source control. Click on the “Application Files” button on the Publish tab for you main project properties, and set the Publish
Status to “Include” and Download Group to “(Required)”.
If you want more control over what “unit” projects get downloaded then you will need to implement something that downloads the “unit” project assemblies and adds them to the catalog. The code
sample at the end is an example using a WCF download manager (http://www.codeproject.com/KB/WCF/WCF_FileTransfer_Progress.aspx). You also need to make sure the Imports allow
recomposition to pick up new matching exports as they appear in the application.
I am still working on how to handle any version issues. I plan to post a sample project when I get all the details worked out (http://www.devgig.com).
void DownloadAssemblies(AggregateCatalog catalog)
// start service client
FileTransferServiceClient client =
foreach (string fileName
// get stream from server
System.IO.Stream inputStream =
long length = client.DownloadFile(fileName,
// write server stream to disk
using (System.IO.FileStream writeStream =
new System.IO.FileStream(SettingsManager.LocalAssemblyCatalogDirectoryPath, System.IO.FileMode.CreateNew, System.IO.FileAccess.Write))
int chunkSize = 2048;
byte buffer = new
// read bytes from input stream
int bytesRead = inputStream.Read(buffer, 0, chunkSize);
if (bytesRead == 0) break;
// write bytes to output stream
writeStream.Write(buffer, 0, bytesRead);
// close service client