Click here to Skip to main content
15,895,011 members
Articles / Programming Languages / C#

LiveCode.NET

Rate me:
Please Sign up or sign in to vote.
4.86/5 (55 votes)
6 May 2002Public Domain3 min read 231.8K   2.5K   170  
Compile C# code on-the-fly. Usage in a plug-in / plug-out component model.
//
//  Handler/Connector classes for domain / assembly / plugin / instance
//
using System;
using System.IO;
using System.Collections;
using System.Windows.Forms;

using MultiPlug.PlugInterface;

namespace MultiPlug.MultiApp
{

	/// <summary> class representing a domain. </summary>
public class DomainConnector : IDisposable
{
	private static int				domainID = 2;
	private string					name;
	private AppDomain				domain;
	private PlugInterfaceFactory	factory;
	private ArrayList				assemblies = new ArrayList();	// array of AssemblyConnector
	
	public DomainConnector()
	{
		name = "Domain" + domainID.ToString();
		domainID++;
		domain = AppDomain.CreateDomain( name );
		factory = (PlugInterfaceFactory) domain.CreateInstance( @"PlugInterface", "MultiPlug.PlugInterface.PlugInterfaceFactory" ).Unwrap();
	}

	public void Dispose()
	{
		factory = null;
		if( assemblies != null )
		{
			foreach( AssemblyConnector ac in assemblies )
				ac.Dispose();
			assemblies.Clear();
			assemblies = null;
		}
			
		// unload the complete app-domain
		if( domain != null )
		{
			AppDomain.Unload( domain );
			domain = null;
		}
	}

	public AssemblyConnector LoadAssembly( string asmName, out ArrayList plugins )
	{
		plugins = null;
		ArrayList plugs = null;
		try {
			plugs = factory.EnumPlugins( asmName );
		}
		catch( Exception )
			{}
		if( plugs == null )
			return null;
		if( plugs.Count < 1 )
			return null;
		plugins = new ArrayList( plugs.Count );
		foreach( string plugName in plugs )
		{
			PluginConnector plugin = new PluginConnector( asmName, factory, plugName );
			plugins.Add( plugin );
		}
		AssemblyConnector ac = new AssemblyConnector( asmName, plugins );
		assemblies.Add( ac );
		return ac;
	}

	public AppDomain Domain
		{ get { return domain; } }

	public string Name
		{ get { return name; } }
}



	/// <summary> class representing a plugin assembly. </summary>
public class AssemblyConnector : IDisposable
{
	private string			name;
	private ArrayList		plugins;		// array of PluginConnector
	
	public AssemblyConnector( string asmName, ArrayList plugins )
	{
		name = asmName;
		this.plugins = plugins;
	}

	public void Dispose()
	{
		if( plugins != null )
		{
			foreach( PluginConnector pc in plugins )
				pc.Dispose();
			plugins.Clear();
			plugins = null;
		}
	}

	public string Name
		{ get { return name; } }
	}


	/// <summary> class representing a plugin. </summary>
public class PluginConnector : IDisposable
{
	private string					name;
	private string					asmName;
	private PlugInterfaceFactory	factory;
	private ArrayList				instances = new ArrayList();	// array of InstanceConnector
	private int						instanceID = 1;
	
	public PluginConnector( string asmName, PlugInterfaceFactory factory, string plugName )
	{
		name = plugName;
		this.asmName = asmName;
		this.factory = factory;
	}

	public void Dispose()
	{
		factory = null;
		if( instances != null )
		{
			foreach( InstanceConnector ic in instances )
				ic.Dispose();
			instances.Clear();
			instances = null;
		}
	}

	public InstanceConnector CreateInstance()
	{
		object[] constructArgs = new object[] { "ctor txt" };
		IPlugInterface iplug = null;
		try {
			iplug = factory.Create( asmName, name, constructArgs );
		}
		catch( Exception )
			{}
		if( iplug == null )
			return null;

		string instanceName = "Instance" + instanceID.ToString();
		instanceID++;
		InstanceConnector instance = new InstanceConnector( instanceName, iplug );
		instances.Add( instance );
		return instance;
	}

	public void ReleaseInstance( InstanceConnector instance )
	{
		instances.Remove( instance );
		instance.Dispose();
	}

	public string Name
		{ get { return name; } }
	}


	/// <summary> class representing one plugin instance, also sinking event callbacks. </summary>
public class InstanceConnector : MarshalByRefObject, IPlugEvent, IDisposable
	{
	private string			name;
	private IPlugInterface	iplug;
	private Control			notifyControl;
	private EventHandler	notifyHandler;
	private int				hint;
	
	public InstanceConnector( string instanceName, IPlugInterface iplug )
	{
		name = instanceName;
		this.iplug = iplug;
	}

	public void Dispose()
	{
		if( iplug != null )
		{
			try {
				iplug.Dispose();
			}
			catch( Exception )
				{}
			iplug = null;
		}
	}

	public string Name
	{	get { return name; } }

	public IPlugInterface Plug
	{	get { return iplug; } }


	public void SetNotifyHandler( Control notifyControl, EventHandler notifyHandler )
	{
		this.notifyControl = notifyControl;
		this.notifyHandler = notifyHandler;
	}

		/// <summary> callback from plugin. WARNING: executed on different thread! </summary>
	void IPlugEvent.PlugNotification( int hint )
	{												// todo: make it thread-safe & deadlock-free
		this.hint = hint;
		if( notifyControl != null )
			notifyControl.Invoke( notifyHandler );		// notify GUI thread about changes
	}

	public int Hint
	{	get { return hint; } }
}


}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under A Public Domain dedication


Written By
Web Developer
Switzerland Switzerland
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions