Skip to content

Personal tools
You are here: Home » SQL Server » SQL Server Articles Archive » Creating and Deploying a Smart Client with Plug-Ins - Part 2: The Application Frame
Seeking new owner for this high-traffic site.
Tap into the potential of this DBA community to expand your business! Interested? Contact us today.
Who Are You?
I am a:
Mainframe True Believer
Distributed Fast-tracker

[ Results | Polls ]
Votes : 3554

Creating and Deploying a Smart Client with Plug-Ins - Part 2: The Application Frame

by Eric Charran

Part 1  |  Part 2

Continuing with the concepts defined and outlined in the previous article, “Creating and Deploying a Smart Client with Plug-Ins,” the smart client application model allows developers to provide a rich and interactive application interface while maximizing the deployment model of Internet applications.

Coupled with this approach is the application model of pluggable interfaces. In this paradigm, developers can abstract horizontally common functionality and provide it to a discrete set of highly specific code modules (i.e., plug-ins). In this fashion, developers can create a framework for applications instead of highly-specific silos. The following sections review, in detail, techniques and guidance that can be used to create the application frame that will host plug-ins.

Application Frame Design Techniques

Because the application frame is a horizontal application providing some layer of generic functionality to the plug-ins, the scope of this article will include a specific function that will be easy to illustrate. This function will be to provide each plug-in with a SQL Server connection. In this fashion, the plug-ins can obtain the SQL Server that the user connected to in the application frame, prior to launching the plug-in. Similarly, developers can substitute this and any other horizontally accessible functionality to the plug-in application.

The application frame’s is a single windows form application that is an MDI parent. The most complex element to the form is the fact that it must contain a method to load an assembly using the Assembly.Load method. Other elements of the application frame form include a menu system comprised of a List View control and a List Box, which enumerates all SQL Servers on the domain using an SQL-DMO method.

The List View is populated from a Web method located within the authentication web service. The same dataset that serves as the List View’s data source contains the assembly information for the plug-ins so the application frame can launch them as MDI children.

Horizontal Application Functionality

As previously stated, the application frame will provide the plug-ins with a specified SQL Server connection so that the plug-ins will not bear the responsibility to obtain connection information individually. The method that provides this capability emulates interface-like behavior. While interface utilization will not fit this model, the principles behind them are useful when implemented from a procedural perspective.

Each plug-in must inherit from a base form class in order to be hosted within the application frame. This base form contains a predefined series of methods and properties that the application frame expects the plug-in to possess. This relationship is depicted in the following diagram.

Figure 1.2: Application frame/plug-in base interaction

In this figure, the NewPlugin.exe exists as a newly developed plug-in to be hosted by the application frame. The developer has inherited the form housed within the PluginBase.dll by setting a .NET project reference to the PluginBase.dll project. This will allow developers to debug into the base dll when invoking its methods, etc. The NewPlugin.exe can now make use of the ConnectedSQLServer property and expose it to the application frame. The NewPlugin.exe assembly can now construct its own connection string based on the value obtained by the application frame.

The following process model can demonstrate this functionality. In this example, the application frame gathers the information from the user with regard to the SQL Server they wish to access. Based on this information gathered, the application frame can pass the connection string to the plug-in’s ConnectedSQLServer property. The resulting procedure is as follows. 

Step Description
Obtain SQL Server connection and authenticate user Using an SQL -DMO method, enumerate all SQL Servers on the network and persist the list to a list box. Allow the user to select a SQL Server from the list box and then use SQL-DMO to authenticate the user to the SQL Server.
Obtain the list of plug-ins available to the user from the authentication service Invoke a Web method to determine based on the user’s credentials, which plug-ins the user has access to. Populate a list view control with the choices.
 On Plug-in selection, launch the assembly and supply its initialization properties
Load the assembly specified by the list view once the user makes a selection and pass it the connected SQL Server. Since the SQL Server has already been connected to, the plug-in does not have to worry about whether the user has access to the SQL Server or not.

Table 1.1: Plug-in instantiation and property assignment process.

The framework of the entire solution is such that if additional information or actions needed to be accessible to all plug-ins, then would need to be accommodated in the code of the application frame and then the appropriate properties and methods would need to be included in the PluginBase.dll.

Loading Assemblies as MDI Children

Since all plug-ins exist as separate .NET assemblies, the application frame must load them as separate assemblies and force them to show as MDI children. This presents a unified perception and interface to the user. The application frame understands how to load these assemblies the same way that users launch the application frame. The application loads the assemblies using the smart client access methodology of running them from the URL.

As illustrated in “Creating and Deploying a Smart Client with Plug-Ins,” Figure 1.1, the user makes a selection from the list view containing the assembly information for each plug-in choice. The application frame contains a method called LoadAssembly(). The purpose of this method is to utilize the assembly information in the menu dataset to invoke the specified assembly as an MDI child and set any properties required. The following is a listing of information that the authentication service returns to the application as part of the plug-in menu dataset.

Data Element  Description  Example
Assembly Full Path  The full path to the assembly, including the executable. In this case, each plug-in is a smart client so it can be invoked from the URL   http://webserver/applicationfolder/plugins/pluginname.exe
Assembly Entry Point In order to launch an assembly from another, the calling assembly must be told where the application all begins. This is usually the fully qualified name of the plug-in’s main form Plugin                            PluginMainForm
Assembly ConfigFile Name                         Because of some complications with config files, this element specifies the application configuration file directly from the URL  http://webserver/applicationfolder/plugins/pluginname.config

Table 1.2: Assembly information used by the application frame.

The first step in the application frame’s LoadAssembly() method is to obtain this information from the dataset which drives the plug-in menu into variables. The selection variable is a string corresponding to the menu choice made by the user.

string assemblyFullPath = null;

string assemblyEntryPoint = null;

string configFile = null;

DataView assemblyView = new
assemblyView.RowFilter = "AssemblyInfo = '" + selection + "'";

foreach(DataRowView drView in assemblyView)

assemblyFullPath = drView["AssemblyFullPath"].ToString();
assemblyEntryPoint = drView["AssemblyEntryPoint"].ToString();
configFile = drView["AssemblyConfigFileName"].ToString();



Table 1.3: Obtain assembly information from the menu dataset.

The next step of the method is to use the System.Reflection.Assembly.LoadFrom method to instantiate the assembly. The LoadFrom() method will obtain an instance of the assembly directly from the URL specified. Conversely it could also obtain an assembly from the user’s machine or a file share. Subsequently, the LoadAssembly() method then obtains an array of types from the assembly and inspects each one.

// Get the types in the assembly

Type[] types = a.GetTypes();

Table 1.4: Obtain an array of types in the plug-in assembly.

While inspecting each type, the LoadAssembly() method searches for the PluginBaseForm. This type will always exist in a plug-in as they are required to inherit from the PluginBase.dll which contains this form’s definition. In order to understand this type, the application frame also has a reference to this PluginBase.dll as well.

Once the instance of the PluginBaseForm is found, it is inspected to determine if it is the assembly’s entry point. In order for the plug-in to run within the application frame, the entry point must inherit from the PluginBaseForm. The instance of the form is then assigned to a local variable which is of the PluginBase.PluginBaseForm() type. This way, the application frame has knowledge of the specific methods and properties not only of the form from the assembly, but from its inherited capabilities from the base Plugin.dll. The method goes on to assign several properties to ensure that the form will be rendered as an MDI child and configures additional initial display properties.

The last steps of the method are to assign the ConnectedSQLServer property and to assign its configuration file path.

foreach(Type t in types)


if(t.BaseType == typeof(PlugInBase.PlugInBaseForm))


if(t.FullName == assemblyEntryPoint)

f = new PlugInBase.PlugInBaseForm();
f = (PlugInBase.PlugInBaseForm)Activator.CreateInstance(t);
f.MdiParent = this; // Set as MDI children
f.Dock = System.Windows.Forms.DockStyle.Fill;
f.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;

if(System.Configuration.ConfigurationSettings.AppSettings["SQLServerRequired"] == "true")


f._ConnectedSQLServer = this.lstSQLServers.SelectedItem.ToString();

f.ConfigFilePath = configFile;

windowLayout = "None";



Table 1.5: Launch of the assembly as an MDI child.

Next Steps

The aforementioned concepts and techniques provide a clear demonstration of how developers can implement their own plug-in application. Specifically, based on the above example, the frame or foundation for plug-ins can be built to host other assemblies, providing a common point of inheritance. In the next article of this three part series, the design techniques for the plug-ins will be reviewed. This article will include techniques and design guidelines for developing, debugging and implementing a plug-in assembly to the application frame. In further articles, the deployment of both the smart client application frame and its associated plug-in assemblies will be covered, as well as some important advice on code access security as it relates to running executables from the URL.


Eric Charran is currently working as a Technical Architect and Web Developer, in Horsham, PA. Eric holds Microsoft Certifications in SQL Server and has significant experience in planning, designing, and modeling n-tier applications using SQL Server 2000, as well as architecting and implementing .NET framework based applications, solutions and Web services. Eric’s other professional skills encompass Database Administration, Data Warehousing and Application Architecture, Modeling and Design, as well as Data Warehouse Transformation and Population using DTS. Eric is also skilled in developing and implementing ASP.NET and Windows forms applications, using technologies such as COM+, the .NET framework, VB.NET and other .NET languages.

Contributors : Eric Charran
Last modified 2006-01-06 02:11 PM


Posted by luber at 2007-07-18 05:22 AM
Really useful article. Thanks a lot :)
Transaction Management
Reduce downtime and increase repeat sales by improving end-user experience.
Free White Paper
Database Recovery
Feeling the increased demands on data protection and storage requirements?
Download Free Report!

Powered by Plone