0 Comments

In our series of building a Windows application with a plugin support, we’ve thus far examined how Structuremap allows the developer to update and add new features into the application without turning it off. In this post we’re going to cover in detail how the mystical “AssembliesFromPathDynamically”-method works.

Out-of-the-box, Structuremap allows the developer to load external assemblies with the help of a AssemblyScanner-class. AssemblyScanner-implements the IAssemblyScanner-interface and in doing so, it has the following interesting methods:

  • AssembliesFromApplicationBaseDirectory
  • AssembliesFromPath

When you build your Structuremap container, you usually do that with the help of Registry-classes. Our sample application only has one registry-class, PluginRegistry:

<span style="color: #606060" id="lnum1">   1:</span> <span style="color: #0000ff">public</span> PluginRegistry()

<span style="color: #606060" id="lnum2">   2:</span> {

<span style="color: #606060" id="lnum3">   3:</span>     Scan( x=&gt;

<span style="color: #606060" id="lnum4">   4:</span>               {

<span style="color: #606060" id="lnum5">   5:</span>                   x.AssembliesFromPathDynamically(<span style="color: #006080">@&quot;.plugins&quot;</span>);

<span style="color: #606060" id="lnum6">   6:</span>                   x.AddAllTypesOf&lt;IPlugin&gt;();

<span style="color: #606060" id="lnum7">   7:</span>               });

<span style="color: #606060" id="lnum8">   8:</span> }

The implementation is really straight forward. Structuremap scans all the assemblies in plugins-directory and adds all the classes which implement the IPlugin-interface into the container. In that code sample you can see our mystery-method again. Here’s why we need it (taken from the Structuremap’s AssemblyScanner-class):

<span style="color: #606060" id="lnum1">   1:</span> assembly = System.Reflection.Assembly.LoadFrom(assemblyPath);

The default behavior for the Structuremap is to load the assembly using System.Reflection.Assembly-class. That causes problems because it makes the Structuremap to lock the dll. And because it’s locked, we can’t update it if our application is running. Here’s what will happen in our sample application if you replace the call to AssembliesFromPathDynamically with AssembliesFromPath in our sample application and click the “Update my features”-button:

locked

And this is why we’re using the AssembliesFromPathDynamically instead of the built-in AssembliesFromPath-method in our sample application. It allows the Structuremap to load the assembly into our application without locking it. Instead of calling the Assembly.LoadFrom with a file path, we pass it a byte array:

<span style="color: #606060" id="lnum1">   1:</span> <span style="color: #0000ff">byte</span>[] assemStream = <span style="color: #0000ff">null</span>;

<span style="color: #606060" id="lnum2">   2:</span> <span style="color: #0000ff">using</span> (FileStream fs = <span style="color: #0000ff">new</span> FileStream(assemblyPath, FileMode.Open))

<span style="color: #606060" id="lnum3">   3:</span> {

<span style="color: #606060" id="lnum4">   4:</span>     assemStream = <span style="color: #0000ff">new</span> <span style="color: #0000ff">byte</span>[fs.Length];

<span style="color: #606060" id="lnum5">   5:</span>     fs.Read(assemStream, 0, (<span style="color: #0000ff">int</span>)fs.Length);

<span style="color: #606060" id="lnum6">   6:</span> }

<span style="color: #606060" id="lnum7">   7:</span>  

<span style="color: #606060" id="lnum8">   8:</span> assembly = System.Reflection.Assembly.Load(assemStream);

You can use the Structuremap.dll from our sample application if you want to try the dynamic loading of assemblies in your own application. Or, you can download and build the required source code from this Structuremap fork.

Please note that for some reason I had hard time to work with the fork. Git marked all the files as changes just after cloning the repository. Changing the Git’s line ending settings didn’t help. So I decided to manually enter the changes in GitHub. I’m sorry for all the typos.

Update 21.8.2010:

I decided to remove the AssembliesFromPathDynamically-method and instead added a new overload to the AssembliesFromPath-method. This method now has a third parameter called “loadWithoutLocking (bool)” and setting it to true I think this change keeps the IAssemblyScanner-interface cleaner.

The sample application has been updated to reflect this change.

0 Comments

In our first view on “How to update your .NET-application on the fly” we saw a simple Windows Forms application which allowed the user to update its features on the fly. What wasn’t shown was how the application used Structuremap’s features to implement the plugin-support. This post will cover that detail.

When a user clicks the “Run my features” –button, the following code is executed:

<span id="lnum1" style="color: #606060">   1:</span> var plugins = container.GetAllInstances&lt;IPlugin&gt;();

<span id="lnum2" style="color: #606060">   2:</span> <span style="color: #0000ff">if</span> (plugins == <span style="color: #0000ff">null</span>)

<span id="lnum3" style="color: #606060">   3:</span>     <span style="color: #0000ff">return</span>;

<span id="lnum4" style="color: #606060">   4:</span>&nbsp;

<span id="lnum5" style="color: #606060">   5:</span> <span style="color: #0000ff">foreach</span> (var plugin <span style="color: #0000ff">in</span> plugins)

<span id="lnum6" style="color: #606060">   6:</span> {

<span id="lnum7" style="color: #606060">   7:</span>     plugin.Run();

<span id="lnum8" style="color: #606060">   8:</span> }

As you can see, the application asks from the container for all the class instances which implement the IPlugin-interface. After that, the collection is just enumerated and each plugin is executed. There’s no magic in there. What happens when user clicks the “Update my features”-button is much more interesting:

<span id="lnum1" style="color: #606060">   1:</span> var appPath = Application.StartupPath;

<span id="lnum2" style="color: #606060">   2:</span>&nbsp;

<span id="lnum3" style="color: #606060">   3:</span> var sourcePath = Path.Combine(appPath, <span style="color: #006080">@"pluginarchiveplugin.dll"</span>);

<span id="lnum4" style="color: #606060">   4:</span> var destinationPath = Path.Combine(appPath, <span style="color: #006080">@"pluginsplugin.dll"</span>);

<span id="lnum5" style="color: #606060">   5:</span>&nbsp;

<span id="lnum6" style="color: #606060">   6:</span> File.Copy(sourcePath, destinationPath, <span style="color: #0000ff">true</span>);

<span id="lnum7" style="color: #606060">   7:</span>&nbsp;

<span id="lnum8" style="color: #606060">   8:</span> ReloadPlugins();

There’s couple things going on in here. First, take a note on the File.Copy. Remember how we already had the “plugin.dll” in our plugins-folder? Shouldn’t this copy operation fail because that dll has already been loaded into the app domain, thus locking the file? Well, it doesn’t fail, meaning the Structuremap hasn’t locked the file. Also, in the last line, there’s a call to ReloadPlugins-method. That method uses some nice functionalities provided by the Structuremap:

<span id="lnum1" style="color: #606060">   1:</span> container.EjectAllInstancesOf&lt;IPlugin&gt;();

<span id="lnum2" style="color: #606060">   2:</span>&nbsp;

<span id="lnum3" style="color: #606060">   3:</span> container.Configure(x =&gt;

<span id="lnum4" style="color: #606060">   4:</span>     x.AddRegistry&lt;PluginRegistry&gt;()

<span id="lnum5" style="color: #606060">   5:</span>     );

In the first line, the container is asked to eject all the instances of classes which implement the IPlugin-interface. If we would call GetAllInstances<IPlugin> after that, the container wouldn’t return anything. In the third line, we’re using the Configure-method to adjust the container on run time. Here we ask it to configure the container with the PluginRegistry. PluginRegistry-class itself looks like this:

<span id="lnum1" style="color: #606060">   1:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> PluginRegistry : Registry

<span id="lnum2" style="color: #606060">   2:</span> {

<span id="lnum3" style="color: #606060">   3:</span>     <span style="color: #0000ff">public</span> PluginRegistry()

<span id="lnum4" style="color: #606060">   4:</span>     {

<span id="lnum5" style="color: #606060">   5:</span>         Scan( x=&gt;

<span id="lnum6" style="color: #606060">   6:</span>                   {

<span id="lnum7" style="color: #606060">   7:</span>                       x.AssembliesFromPathDynamically(<span style="color: #006080">@".plugins"</span>);

<span id="lnum8" style="color: #606060">   8:</span>                       x.AddAllTypesOf&lt;IPlugin&gt;();

<span id="lnum9" style="color: #606060">   9:</span>                   });

<span id="lnum10" style="color: #606060">  10:</span>     }

<span id="lnum11" style="color: #606060">  11:</span> }

The PluginRegistry adds all the assemblies from the plugins-folders and asks the Structuremap container to find all the classes which implement the IPlugin-interface.

If you know the Structuremap’s api well, you may be wondering where that AssembliesFromPathDynamically came from. We will get to that in the next post.

Download

Like mentioned in the first post of this series, the full source code for the sample application is available from the GitHub.

22 Comments

Some applications require that they’re constantly running. Whether they are mission critical systems, web servers or irc bots, users will be affected if the application is taken down even for a short period.  Imagine what you could if your application could be upgraded and changed without ever closing it down? It’s easy to list some benefits for an application like that:

  • Update wrongly behaving parts of your programs without shutting it down completely
  • Test your changes rapidly
  • Allow an easy deployment of application plugins

In this post we’re going to take a look on a simple Windows Forms application which can be extended through the use of plugins. The application demonstrates two features which are required for the always running systems:

  • Updating an existing feature on the fly
  • Installing a new feature on the fly

You can find the link to the source code and executables from the bottom of this post.

Infrastructure

The sample application is written with the following tools:

  • Visual Studio 2010
  • .NET Framework 4.0
  • Structuremap IoC-container

Sample application

Did I mention that our sample application is simple? Well, here it is in our full glory.

app

Our application is a simple Windows Forms client. The application’s plugins are stored in binplugins –folder and they are .NET-assemblies. One assembly (dll-file) can contain multiple plugins for our application. To keep things simple, every plugin implements an IPlugin-interface.

When you run the application and click the “Run my features”, it will execute all the functionalities provided by the plugins. When you click the “Update my features” and then the “Run” button, you’ll see how an existing feature has been updated on the fly. If you then click “Add new features” and then again “Run”, you’ll see how more functions has been added to the application.

Behind the scenes the “Update my features” will replace the binpluginsplugin.dll-file with a plugin.dll from a binpluginsarchive-folder. “Add new features” will copy the plugin2.dll from the archive folder into the plugins-directory.

Full-blown example?

For a more complicated application you can see the source code of the following irc bot, which allows the developer to add new commands (AuthenticateMe etc.) and irc event handlers (triggered by events like UserChangedTopic) without dropping the bot from the server. Existing commands and event handlers can be also modified on the fly.

Future posts

This is not all. In the following days we’re going to jump to the details of the implementation behind this simple application. At least the following topics will be covered:

Download

You can browse and download the sample application’s source from GitHub.

1 Comments

Solving this wasn’t obvious to me so here’s a short guide for those who encounter the same problem.

If you are using IIS Express and you’re configuring the web sites through the applicationHost.config, you may encounter the following error when accessing your page:

HTTP Error 500.19 - Internal Server Error
The requested page cannot be accessed because the related configuration data for the page is invalid.

This may happen if you haven’t configured any application to the root of your site. In my case, the initial configuration looked like the following:

&lt;site name=<span style="color: #006080">"mySite"</span> id=<span style="color: #006080">"1"</span> serverAutoStart=<span style="color: #006080">"true"</span>&gt;

    &lt;application path=<span style="color: #006080">"/"</span>&gt;

        &lt;virtualDirectory path=<span style="color: #006080">"/"</span> physicalPath=<span style="color: #006080">"C:sitesmySite"</span> /&gt;

    </application>            

    <bindings>

        &lt;binding protocol=<span style="color: #006080">"http"</span> bindingInformation=<span style="color: #006080">":8080:localhost"</span> /&gt;

    </bindings>

</site>

This worked nicely. The problems began when I tried to move my site to the localhost/mySite:

&lt;site name=<span style="color: #006080">"mySite"</span> id=<span style="color: #006080">"1"</span> serverAutoStart=<span style="color: #006080">"true"</span>&gt;

    &lt;application path=<span style="color: #006080">"/mySite"</span>&gt;

        &lt;virtualDirectory path=<span style="color: #006080">"/"</span> physicalPath=<span style="color: #006080">"C:sitesmySite"</span> /&gt;

    </application>            

    <bindings>

        &lt;binding protocol=<span style="color: #006080">"http"</span> bindingInformation=<span style="color: #006080">":8080:localhost"</span> /&gt;

    </bindings>

</site>

After this change, I couldn’t access my site anymore. I was greeted with the “configuration data for the page is invalid”. But a simple change fixed it:

&lt;site name=<span style="color: #006080">"mySite"</span> id=<span style="color: #006080">"1"</span> serverAutoStart=<span style="color: #006080">"true"</span>&gt;

    &lt;application path=<span style="color: #006080">"/"</span>&gt;

        &lt;virtualDirectory path=<span style="color: #006080">"/"</span> physicalPath=<span style="color: #006080">"C:sitesfakesite"</span> /&gt;

    </application>            

    &lt;application path=<span style="color: #006080">"/mySite"</span>&gt;

        &lt;virtualDirectory path=<span style="color: #006080">"/"</span> physicalPath=<span style="color: #006080">"C:sitesmySite"</span> /&gt;

    </application>

    <bindings>

        &lt;binding protocol=<span style="color: #006080">"http"</span> bindingInformation=<span style="color: #006080">":8080:localhost"</span> /&gt;

    </bindings>

</site>

Note. The same applies to the virtualDirectory. You must have one virtualDirectory-setting pointing into your application’s root.

0 Comments

There’s something in RavenDB which every platform developer should copy into their own platforms: Well written exception messages. Here’s one example:

The maximum number of requests (30) allowed for this session has been reached.
Raven limits the number of remote calls that a session is allowed to make as an early warning system. Sessions are expected to be short lived, and
Raven provides facilities like Load(string[] keys) to load multiple documents at once and batch saves.
You can increase the limit by setting DocumentConvention.MaxNumberOfRequestsPerSession or DocumentSession.MaxNumberOfRequestsPerSession, but it is
advisable that you'll look into reducing the number of remote calls first, since that will speed up your application signficantly and result in a
more responsive application.

Not only does this tell you what went wrong, it also tells you why and also offers advices on how to fix it. Does it get any better than this?

Good exceptions can be real time-savers.