Dundas Data Visualization Support Site
Dundas Support Site Home  |  Contact Us  |  Dundas Home  
Contact Us via Email
Home > Dundas Gauge

Dynamic Assembly Loading using Reflection

 

Introduction

Assemblies can be loaded at run time through the System.Reflection namespace. While assembly calls are more difficult than normal when using this method, it has a few unique advantages. This article explains how using Reflection can be advantageous. Included in this article is a sample demonstrating how to load Dundas Chart for .NET through reflection, populate it with data, and set a property.

Background

One situation in which using Reflection to load an assembly proves advantageous is where an application must be built without having references to the assembly itself. This can be useful when you have 2 versions of your product: one which uses the Dundas Software assembly, and one which does not. Using Reflection in this case would mean that neither version needs a direct reference to the Dundas Software assembly.

Using Reflection to load assemblies lets you avoid dealing with directives at the top of the ASPX page (in ASP.NET), as well as references within the Web.Config file. Furthermore, using Reflection gives the freedom to place assemblies anywhere on the hard drive and avoid registering them into the GAC.

At the bottom of this article is a sample program available for download (C#, ASP.NET, VS2005) which shows how Reflection can be used to load Dundas Chart. To use this sample, simply extract the .zip file into a directory, open Visual Studio 2005, chose "file", "open->" and select "Web Site". Point to the extracted directory and press "Ok".

How the Sample Works

This sample works by using the System.Reflection.Assembly object; the Assembly is used to load the Chart .dll into the program. Once the assembly has been loaded, the type of the root Chart object is retrieved. This is the same as declaring an object of type Dundas.Charting.WebControl.Chart. The last step in the initialization process is to instantiate the Chart.

// Create a new System.Reflection.Assembly object.
Assembly chartAssembly = null;

// Load the assembly into the program.
string webAppPath = this.Server.MapPath(".");
chartAssembly = Assembly.LoadFile(webAppPath + @"\DundasWebChart.dll");

// Set the namespace to the root Chart object.
string chartNamespace = "Dundas.Charting.WebControl.Chart";

// Gets the type of the assembly (which will be the Chart object).
Type type = chartAssembly.GetType(chartNamespace);

// Gets a reference to the constructor of the object.
ConstructorInfo constructor = type.GetConstructor(new Type[0]);

// Instantiates the Chart.
object chartHolder = constructor.Invoke(null);
Once the Chart has been instantiated and loaded, everything that can normally be done with Chart can still be done, just in a different way. For example, to set the BackColor property of Chart to Magenta, the following code is used:
if (chartHolder != null)
{
	// Reflect over the script holder object in order to
	// find out whether code of the event is provided.
	type = chartHolder.GetType();

 	PropertyInfo piBackColor = type.GetProperty("BackColor");
	piBackColor.SetValue(chartHolder, Color.Magenta, null);
}
Calling a method is also done differently. To call a method, it must first be found and identified (for the correct overload), and then Invoke is used to call the actual method. Below is an example of how to call the DataBindCrossTab method. The full source code to this is available within the Sample which uses an Access database. Much of the database code has been omitted for brevity.
MethodInfo miDataBindCrossTab = type.GetMethod("DataBindCrossTab", new Type[] { typeof(System.Collections.IEnumerable), typeof(string), typeof(string), typeof(string), typeof(string) });
if (miDataBindCrossTab != null)
{
	// resolve the address to the Access database
	string fileNameString = webAppPath + @"\chartdata.mdb";

	...

	// create a database reader
	OleDbDataReader myReader = myCommand.ExecuteReader(CommandBehavior.CloseConnection);

	// since the reader implements and IEnumerable, pass the reader directly into the DataBindCrossTab
	miDataBindCrossTab.Invoke(chartHolder, new object[] { myReader, "Name", "Year", "Sales" , ""});

	...
}

Accessing a collection and properties within a collection are not shown within the downloadable sample. However, the following is a code snippet demonstrating how the ChartAreas collection can be accessed, and the BackColor changed on the first (default) ChartArea. Pasting this code into the sample will result in the ChartArea's BackColor becoming orange.

// Get a reference to the chart area collection.
PropertyInfo piChartAreas = type.GetProperty("ChartAreas");
object ChartAreasCollection = piChartAreas.GetValue(chartHolder, null);

// Get the number of items in the collection (ensure one exists).
PropertyInfo piCount = piChartAreas.PropertyType.GetProperty("Count");
int myCount = (int)piCount.GetValue(ChartAreasCollection, null);

if (myCount > 0)
{
	// Get a reference to the first chart area (ChartAreas[0]).
	PropertyInfo piChartArea = piChartAreas.PropertyType.GetProperty("Item");
	object ChartArea = piChartArea.GetValue(ChartAreasCollection, new object[] { 0 });

	// Get the BackColor property and set it to orange.
	PropertyInfo piChartAreaBackColor = piChartArea.PropertyType.GetProperty("BackColor");
	piChartAreaBackColor.SetValue(ChartArea, Color.Orange, null);
}

While this is quite a different way to set the BackColor from the normal method of setting the property Chart.BackColor, it achieves the same results. Once an understanding of how an assembly is accessed through Reflection is achieved, creating programs that use this method is an easy task and can prove invaluable in certain situations.

 

Additional Downloads:

Sample (VS2005, C#, ASP.NET)
PoorExcellent