Click here to Skip to main content
12,953,175 members (46,521 online)
Click here to Skip to main content
Add your own
alternative version


99 bookmarked
Posted 24 Dec 2003

Using SmartAssembly for Smart Client

, 24 Dec 2003
Rate this:
Please Sign up or sign in to vote.
A solution that uses "pull model" to keep assemblies of an application up to date.

Sample Image - maximum width is 600 pixels


For organizations that run information systems, it's a common problem to keep all instances of a desktop application up to date with the latest version of executables, libraries, configuration and other files. It always costs great deal of resources (human and time). Ideally, administrators and support engineers would like to deploy the updated files once, to a central server, and have the updated files automatically replicated to each desktop installation. The SmartAssembly is such a solution that uses "pull model" to do so for .NET applications.

.NET framework has provided the support for "Smart Client" applications. You can config <DEPENDENTASSEMBLY> nodes in the configuration file (see MSDN for details) and let the runtime to download the associated assemblies. However, there are some weaknesses:

  1. The configuration is too simplex and has a lack of flexibility.
  2. The download progress is a "blackbox", and not friendly to the end users.
  3. In the case of late binding, if you load an assembly by its weak name (not specify the version, public key and culture), the runtime will open a HTTP connection to check the remote one every time when you load the same assembly. Of course, it will waste a great deal of time if you need to load some assemblies frequently.

In addition, Microsoft has published an Application Block named Updater which also provides a "pull model" solution to automatically download application updates from a central location. But it does not work on-the-fly. By contraries, it frequently checks the remote manifest file to determine whether there is a need to do update. If so, it starts an Updater process and shuts down the user application to download the changed files. After downloading all the changed files, it then starts the user application again.

SmartAssembly is designed to meet the following requirements:

  1. Make the download progress controllable, visible and customizable.
  2. Support break-and-resume downloading.
  3. Provide a framework for supporting compressed file.
  4. Ease the configuration work for deployers.
  5. Provide deployers with flexibility to configure the system.
  6. Provide developers with customizability and extensibility.

Working principle

There is a set of Resolve events defined in classes AppDomain and Assembly. These events provide developers a chance to resolve assemblies, resources and modules by themselves. SmartAssembly only uses the AssemblyResolve event. When that event is fired, SmartAssembly searches the configuration for the associated codebase URI, then downloads the assembly according to the URI and save it to local, at last loads the assembly and returns it back to AppDomain.

Using SmartAssembly

It's divided into two parts to describe how to use SmartAssembly. At first, it's required to add a piece of code in your application. Then, write the configuration file and deploy your application.


By the way, there is a CHM file accompanied with the source package. You can refer it for the details about how to use SmartAssembly.

1. Create a SmartAssemblyManager instance

The class SmartAssemblyConfig is used to create a SmartAssemblyManager instance from a SmartAssembly configuration section. There are three ways to do so.

  1. Load from the application configuration file. By this way, the returned SmartAssemblyManager instance is also SmartAssemblyManager.CurrentManager, and its CurrentDomain property has already been set to AppDomain.CurrentDomain. In contrast, the other two ways just create a new SmartAssemblyManager instance:
    SmartAssemblyManager sam = 
     as SmartAssemblyManager;
  2. Load from an individual configuration file for SmartAssembly:
    SmartAssemblyManager sam = SmartAssemblyConfig.Create("c:\test.xml");
  3. Load from a prepared configuration XmlNode:
    // Prepare the configuration XmlNode
    XmlNode section = ...;
    SmartAssemblyManager sam = SmartAssemblyConfig.Create(section);
    if( null != sam ) {
        sam.CurrentDomain = AppDomain.CurrentDomain;

2. Enable SmartAssembly

To enable SmartAssembly, you need to set the CurrentDomain property of the SmartAssemblyManager instance to an AppDomain.

if( null != sam ) {
    sam.CurrentDomain = AppDomain.CurrentDomain;

As described above, if you create SmartAssemblyManager instance from the application configuration file, and just want to handle the AppDomain.CurrentDomain, then you can skip this step.

3. Customize the routine to download SmartAssembly configuration file

SmartAssembly configuration file can be an individual file, or even a database record, thus you can download it or get it from the database. SmartAssemblyConfig provides a static delegate for you to do so.

Public static DownloadConfigDelegate DownloadConfigCallback;

4. Customize the routine to uncompress a file

SmartAssembly does not provide that function in this version. However, it provides a well defined framework to ease your work. All that you need to do is to develop an ExtractFileInZipDelegate function and handle the following delegate of the SmartAssemblyManager instance, then follow the configuration rules for compressed files (see the Deploying section for details).

public ExtractFileInZipDelegate ExtractFileInZipCallback;

5. Customize other routines

SmartAssembly also provides customizability for LoadAssembly, LoadlocalAssembly, DownloadFile and so on.

public event LoadAssemblyEventHandler CustomLoadAssembly;
public event LoadAssemblyEventHandler CustomLoadlocalAssembly;

public event SmartAssemblyEventHandler CustomDownloadFile;
public event SmartAssemblyEventHandler CustomDownloadCompleted;
public event DownloadProgressEventHandler CustomDownloading;
public event SmartAssemblyCancelEventHandler BeforeDownload;
public event SmartAssemblyEventHandler AfterDownload;


The deploying work is focused on how to write the configuration file. This section will give you the details to configure SmartAssembly.


This is the root node of the configuration.

<A href="#node_sac"><smartAssemblyConfiguration></A>  
  <A href="#node_sc"><smartConfig></A>
  <A href="#node_cd"><cacheDirectory></A>
  <A href="#node_ns"><netSetting></A>
  <A href="#node_ll"><loadLogic></A>
  <A href="#node_da"><dependentAssembly></A>
    <A href="#node_ai"><assemblyIdentity></A>
    <A href="#node_cb"><codeBase></A>
    <A href="#node_br"><bindingRedirect></A>

Child Element



<smartConfig>Specifies the setting for smart configuration file.N
<cacheDirectory>Specifies the settings for cache directories.Y
<netSetting>Specifies the arguments for network connection.N
<loadLogic>Specifies the logic to load assemblies.N
<dependentAssembly>Encapsulates binding policy and assembly location for each assembly.N

2. smartConfig

Configures the individual SmartAssembly configuration file. If this node exists, SmartAssembly will try to load configuration from that setting and the other nodes will be ignored.

<A href="#node_sac"><smartAssemblyConfiguration></A>
  <A href="#node_sc"><smartConfig></A>





hrefSpecifies the URL where SmartAssembly can find the configuration file.N 
filePathSpecifies the full file path where SmartAssembly saves the configuration file to.N 
tryLocalTries the local file if failed to download the remote one.Ntrue

3. cacheDirectory

Settings for local cache directory.

<A href="#node_sac"><smartAssemblyConfiguration></A>
  <A href="#node_cd"><cacheDirectory></A>





pathSpecifies the cache path for SmartAssembly to store assemblies.Y 
typeSpecifies the type of the cache path. (Enum: KeepNewestOnly, KeepAllVersions, KeepAllByHashCode)NKeepNewestOnly
packageFilePathSpecifies the cache path where SmartAssembly stores compressed files.N 
shadowCopyCachePathSpecifies the cache directory for ShadowCopy.N 
shadowCopyExtraDirsSpecifies the extra directories for ShadowCopy. N 

4. netSetting

Settings for network arguments.

<A href="#node_sac"><smartAssemblyConfiguration></A>
  <A href="#node_ns"><netSetting></A>





agentNameSpecifies the agent name for a HttpRequest.N 
bufferSizeSpecifies the size of the download buffer.N4096
timeoutSpecifies the the time-out value for a HttpRequest. N-1

5. loadLogic

The logics to load assemblies.

<A href="#node_sac"><smartAssemblyConfiguration></A>
  <A href="#node_ll"><loadLogic></A>





notCheckRemoteWhileMatchedSpecifies whether to check the remote file (assembly) even when the local one matched with the request completely.Ntrue
downloadNewerOnlySpecifies whether to do download only when the remote file is newer than local one.Nfalse
tryLatestVersionWhileNotMatchSpecifies whether to use the highest version that is configured in the configuration file automatically.Ntrue
smartMatchSpecifies whether to use "Smart Match" technique. Ntrue
loadSymbolsSpecifies whether to try downloading the symbol file(s) associated the assemblies that are to be resolved. Nfalse
symbolsFileExtNameSpecifies the extension of symbol file(s) that will be used to calculate the URI. Npdb
loadMethodSpecifies the method to load Assembly. (Enum: Directly, ViaMemoryStream, ShadowCopy)NDirectly
identifiedByNameSpecifies whether to use the weak name to identify an assembly. Nfalse
workOfflineSpecifies whether to work in offline mode. Nfalse
baseHrefSpecifies the base URI, which will be used to calculate the URI of the assemblies. N 
defaultZipFileSpecifies the default compressed file name, which will be used to calculate the URI of the assemblies that have not been configured. N 

6. dependentAssembly

Encapsulates binding policy and assembly location for each assembly. Use one <dependentAssembly> element for each assembly.

<A href="#node_sac"><smartAssemblyConfiguration></A>
  <A href="#node_da"><dependentAssembly></A>
      <A href="#node_ai"><assemblyIdentity></A>
      <A href="#node_cb"><codeBase></A>
      <A href="#node_br"><bindingRedirect></A>

Child Element



<assemblyIdentity>Contains identifying information about the assembly. This element must be included in each <dependentAssembly> element.Y
<codeBase>Specifies where the runtime can find a shared assembly if it is not installed on the computer.N
<bindingRedirect>Redirects one assembly version to another or even to another assembly.N

6.1. assemblyIdentity

Contains identifying information about the assembly.

<A href="#node_sac"><smartAssemblyConfiguration></A>
  <A href="#node_da"><dependentAssembly></A>
     <A href="#node_ai"><assemblyIdentity></A>





nameThe name of the assembly.Y 
publicKeyTokenA hexadecimal value that specifies the strong name of the assembly.N 
cultureA string that specifies the language and country/region of the assembly.N 

6.2. codeBase

Specifies where the common language runtime can find an assembly.

<A href="#node_sac"><smartAssemblyConfiguration></A>
  <A href="#node_da"><dependentAssembly></A>
    <A href="#node_cb"><codeBase></A>





versionSpecifies the version of the assembly the codebase applies to. The format of an assembly version number is Valid values for each part of the version number are 0 to 65535N 
hrefSpecifies the URL where the runtime can find the specified version of the assembly.N 

6.3. bindingRedirect

Redirects one assembly version to another or even to another assembly.

<A href="#node_sac"><smartAssemblyConfiguration></A>
  <A href="#node_da"><dependentAssembly></A>
      <A href="#node_br"><bindingRedirect></A>






Specifies the version of the assembly that was originally requested. There are three possible formats:

  • Single: n.n.n.n
  • Range: n.n.n.n - n.n.n.n or n.n.* (same as n.n.0.0 - n.n.65535.65535)
  • Collection: n.n.n.n; n.n.n.n; n.n.n.n; ...

Specifies the version of the assembly or a new assembly to use instead of the originally requested version. The format of a new assembly should like this:

NewAsm, Version=, Culture=en-us, PublicKeyToken=


A completed example

  <!-- Declaring custom config  section parsing class -->
    <section name="smartAssemblyConfiguration" 

      type="Lightning.SmartAssemblyConfig, SmartAssembly"/>
    <!--smartConfig temp="%ComAppData%\Assembly\config.xml"
           href="http://localhost/Assembly/Test.xml" /-->
    <cacheDirectory path="%ComAppData%\Assembly\Origin"


            packageFilePath="%ComAppData%\Assembly\ZipFiles" />
    <netSetting agentName="Smart Assemlbly Manager"

          bufferSize="8182" timeout="-1"

          proxyMode="" />
    <loadLogic notCheckRemoteWhileMatched="true"








          baseHref="http://localhost/Assembly/" />

      <assemblyIdentity name="MainControl" publicKeyToken="" culture="" />
      <codeBase version="" href="old/MainControl.dll"/>
      <assemblyIdentity name="SubControl1"


                culture="" />
      <codeBase version="" href="old/SubControl1.dll"/>
      <codeBase version="" href="new/SubControl1.dll"/>
      <bindingRedirect oldVersion=";" newVersion="" />
      <bindingRedirect oldVersion="1.0.*" newVersion="" />
      <bindingRedirect oldVersion=" -" newVersion="" />
      <assemblyIdentity name="SubControl2" publicKeyToken="" culture="" />
      <codeBase version="" href="old/SubControl2.dll"/>
      <assemblyIdentity name="MainControl.resource" publicKeyToken="" culture="" />
      <bindingRedirect oldVersion="*" 

        newVersion="MainControl.resource, Version=, Culture=, PublicKeyToken=" />

About the demo

There are three projects in the demo solution:

SmartAssemblySmartAssembly library.
TestThe demo application which can be executed stand alone or be loaded by IE (see the readme.txt for details.)
TestControlThe demo assembly which will be "SmartAssemblied".

Points of Interest

There are some tips for deploying, for example:

  • Deciding where to set the cache directory to, to AppBaseDir, to AppData or to ComAppData.
  • How to package the assemblies if you use compressed file(s), as an application, as a package or some other strategies?


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

Surain Shen
Software Developer (Senior)
China China
No Biography provided

You may also be interested in...


Comments and Discussions

Generallittle bug Pin
sergey.glotov24-Mar-10 2:54
membersergey.glotov24-Mar-10 2:54 
QuestionModifing bindingRedirect newversion Pin
rawatjeet12-Sep-07 20:55
memberrawatjeet12-Sep-07 20:55 
GeneralNothing Happens Pin
misticat26-Feb-05 5:55
membermisticat26-Feb-05 5:55 
GeneralRe: Nothing Happens Pin
Surain Shen7-Mar-05 14:22
memberSurain Shen7-Mar-05 14:22 
GeneralDownload full application assemblies Pin
gthevenot13-Dec-04 3:50
membergthevenot13-Dec-04 3:50 
GeneralRe: Download full application assemblies Pin
Surain Shen13-Dec-04 17:20
memberSurain Shen13-Dec-04 17:20 
GeneralRe: Download full application assemblies Pin
gthevenot13-Dec-04 22:24
membergthevenot13-Dec-04 22:24 
GeneralProxy Issues Pin
Shayne Boyer24-Nov-04 5:59
memberShayne Boyer24-Nov-04 5:59 
GeneralRe: Proxy Issues Pin
Surain Shen25-Nov-04 16:56
memberSurain Shen25-Nov-04 16:56 
QuestionStart download process from code? Pin
MortenOvergaard15-Oct-04 1:18
memberMortenOvergaard15-Oct-04 1:18 
AnswerRe: Start download process from code? Pin
Surain Shen17-Oct-04 20:44
memberSurain Shen17-Oct-04 20:44 
GeneralRe: Start download process from code? Pin
MortenOvergaard17-Oct-04 20:52
memberMortenOvergaard17-Oct-04 20:52 
GeneralRe: Start download process from code? Pin
Surain Shen25-Oct-04 17:13
memberSurain Shen25-Oct-04 17:13 
GeneralNo CHM File Pin
Cougarman5-Oct-04 10:19
memberCougarman5-Oct-04 10:19 
GeneralRe: No CHM File Pin
Surain Shen28-Nov-04 21:39
memberSurain Shen28-Nov-04 21:39 
GeneralVery well done! Pin
Michael Coyle16-Jul-04 9:30
memberMichael Coyle16-Jul-04 9:30 
Generalcontract work on this smart download Pin
shanthu16-Apr-04 6:45
membershanthu16-Apr-04 6:45 
GeneralCompilation Pin
mikasa30-Dec-03 4:19
membermikasa30-Dec-03 4:19 
GeneralRe: Compilation Pin
Surain Shen30-Dec-03 17:08
memberSurain Shen30-Dec-03 17:08 
GeneralRe: Compilation Pin
mikasa31-Dec-03 2:44
membermikasa31-Dec-03 2:44 
GeneralRe: Compilation Pin
Surain Shen1-Jan-04 17:13
memberSurain Shen1-Jan-04 17:13 
GeneralRe: Compilation Pin
JasonSmith2-Jan-04 6:37
memberJasonSmith2-Jan-04 6:37 
GeneralRe: Compilation Pin
mikasa2-Jan-04 6:43
membermikasa2-Jan-04 6:43 
GeneralFusion Pin
Heath Stewart28-Dec-03 4:43
editorHeath Stewart28-Dec-03 4:43 
GeneralRe: Fusion Pin
Surain Shen28-Dec-03 16:02
memberSurain Shen28-Dec-03 16:02 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170525.1 | Last Updated 25 Dec 2003
Article Copyright 2003 by Surain Shen
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid