SIGN UP MEMBER LOGIN:    
ARTICLE

Loading an Assembly on Demand

Posted by Nitya Sharma Articles | C# Assemblies January 28, 2012
This article shows how to load a .NET assembly dynamically on demand. It explains how an assembly can loaded in a separate AppDomain, so unloading is not required.
Reader Level:

Introduction

In this article I'll show you how to load an assembly dynamically on demand. Recently I worked on a project where I needed to load the same assembly from different code bases. Assemblies were located in different locations as per the environment (dev/qa/uat/prod). Also I wanted to load them into a different application domain, so they will work in their own domain and will not interfere with any of the other tasks. When I am done with the assembly, I can unload them.

Current AppDomain vs new AppDomain

The Current application domain is the AppDomain, where your current application is running. If you load assemblies in the same AppDomain, they will be locked, and cannot be unloaded. It will remain there until you exit from the application. This situation fails the requirement of loading multiple assemblies. If an assembly is loaded in a different AppDomain then it will allow us to unload the AppDomain at any point of time and release memory.

Instantiating Class

If an assembly is loaded into the same AppDomain, then the class can be instantiated in the usual way. But if an assembly is loaded into a different AppDomain then it can be instantiated using reflection. Another way is an interface. However this interface should be implemented in the assembly which is being loaded dynamically. Here I am going over a second method where, I created an interface in an assembly which is being referered by both assemblies; the current appdomain assembly and the assembly which I want to load dynamically.

I wanted to create an AddIn for outlook which pushes a meeting from outlook to my application. I wanted to allow pushing the meeting to a different environment based on the option the user selects. These options are available based on the user's group. I am not going to discuss an Outlook AddIn here. I will discuss that in another article dedicated to Outlook.

I created a an assembly AddInCommon where I created an interface IMyAddIn and implemented it in a MyAddIn abstract class.

public interface IMyAddin
{
   void ShowMessage();
    void Increment();
}

public abstract class MyAddIn : MarshalByRefObject, IMyAddin
{
    public abstract void ShowMessage();
    public abstract void Increment();
}

This class will be inherited in the class of the dynamically loaded assembly. 

[Serializable]

public class MyClass

{

    public int counter = 0;

    public string ShowMessage()

    {

        Console.WriteLine("Assembply Path : " + Assembly.GetExecutingAssembly().CodeBase);

        Console.WriteLine("MDLibOne.MyClass.ShowMessage");

         return "Assembply Path : " + Assembly.GetExecutingAssembly().CodeBase;

    }

 

    public void Increment()

    {

        Console.WriteLine("Counter : " + ++counter);

     }

}

 

MyClass is Serializable because this class will be used in the currentAppDomain, while it is defined in its own assembly. An object needs to be serialized and deserialized back in the currentAppDomain. Both application domains have different memory allocations and can't share the object. Create an AppDomainSetup for each codebase you want to load. The following example creates the AppDomainSetup and stores them in a dictionary, so I don't do setup again to create an application domain each time when we want to instantiate a class. This also allows me to unload.

AssemblyLoader class

This class is responsible for managing the lifetime of AppDomains.

AppDomainSetup domainSetup = new AppDomainSetup();

        domainSetup.ApplicationName = Path.GetFileNameWithoutExtension( file.Value.ToString() );

        domainSetup.ConfigurationFile = Path.GetFileName(file.Value.ToString()) + ".Config";

        domainSetup.ApplicationBase = Path.GetDirectoryName(file.Value.ToString());

         AppDomain appDomain = AppDomain.CreateDomain(domainSetup.ApplicationName, null, domainSetup);

         _appDomains.Add(file.Key.ToString(), appDomain);

         MyClass addin = appDomain.CreateInstanceAndUnwrap(domainSetup.ApplicationName, domainSetup.ApplicationName + ".MyClass") as MyClass;

         _addIns.Add(file.Key, addin);

Calling the AddIn:

private void button1_Click(object sender, EventArgs e)

    {

        MDLibOne.MyClass c = new MDLibOne.MyClass();

         MessageBox.Show(c.ShowMessage()); 

        AssemblyLoader addInLoader = new AssemblyLoader();

        foreach (KeyValuePair addIn in addInLoader.AddIns)

        {

            MessageBox.Show(addIn.Value.ShowMessage());

        }

    }

Wrapping Up

This example will show that it is loading from appropriate location. But still it has an issue that the object created has a short time span. The object created with this method will soon expire and will throw an exception. The object will be timed out after some time. The lifetime will be decided by the source assembly. I am going to discuss this in my next article.

Login to add your contents and source code to this article
share this article :
post comment
 

Nice article.

Posted by Alok Pandey Jan 29, 2012

Its a good and useful article for those who want to learn how to load a .NET assembly dynamically on demand.

Posted by Daisy Krause Jan 29, 2012

Will surely implement it

Posted by Sonakshi Singh Jan 29, 2012
Nevron Gauge for SharePoint
Become a Sponsor
PREMIUM SPONSORS
  • ceTE software specializes in components for dynamic PDF generation and manipulation. The DynamicPDF™ product line allows you to dynamically generate PDF documents, merge PDF documents and new content to existing PDF documents from within your applications.
    Finally – a virtual platform that delivers next-generation Windows Server 2008 Hyper-V virtualization technology from a managed hosting partner you can truly depend on. Visit www.maximumasp.com/max for a FREE 30 day trial. Hurry offer ends soon. Climb aboard the MaxV platform and take advantage of High Availability, Intelligent Monitoring, Recurrent Backups, and Scalability – with no hassle or hidden fees. As a managed hosting partner focused solely on Microsoft technologies since 2000, MaximumASP is uniquely qualified to provide the superior support that our business is built on. Unparalleled expertise with Microsoft technologies lead to working directly with Microsoft as first to offer IIS 7 and SQL 2008 betas in a hosted environment; partnering in the Go Live Program for Hyper-V; and product co-launches built on WS 2008 with Hyper-V technology.
6 Months Free & No Setup Fees ASP.NET Hosting!
Become a Sponsor