Here’s a small all-in-one example of how to add render enabled objects across AppDomains. It’s dead small so don’t expect to see lovely cleanup code or fancy loading of extra assemblies. Just a quick-and-dirty new AppDomain render. Debug output will show it running from it’s new AppDomain.
This should be a good starting point for anyone looking to do something similar.
using System;
using System.Collections;
using System.Reflection;
using Microsoft.SPOT;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Touch;
namespace ApplicationShell
{
public class ApplicationShell : Application
{
private static ApplicationShell _application;
private static ASWindow _desktop;
private static Controller _controller;
public static void Main()
{
// Instance of the Application
_application = new ApplicationShell();
// Instance of the Controller
_controller = new Controller();
// Instance of the Desktop
_desktop = new ASWindow(_controller);
_controller.setDesktop(_desktop);
initializeTouch();
// Run Application
_application.Run(_desktop);
}
private static void initializeTouch()
{
Touch.Initialize(_application);
TouchCollectorConfiguration.CollectionMethod = CollectionMethod.Native;
TouchCollectorConfiguration.CollectionMode = CollectionMode.GestureOnly;
}
}
interface IController
{
form addForm();
}
[Serializable]
public class Controller : MarshalByRefObject, IController
{
private ASWindow _desktop;
public void setDesktop(ASWindow desktop)
{
_desktop = desktop;
}
public form addForm()
{
form frm = new form();
_desktop.addForm(frm);
return frm;
}
}
public class ASWindow : Window
{
private ArrayList _forms = new ArrayList();
private DynamicLoading _dl = new DynamicLoading();
private Controller _controller;
public ASWindow(Controller controller)
{
_controller = controller;
}
public void addForm(form form)
{
_forms.Add(form);
Invalidate();
}
public override void OnRender(Microsoft.SPOT.Presentation.Media.DrawingContext dc)
{
dc.DrawRectangle(new SolidColorBrush(Color.Black), null, 0, 0, 320, 240);
for (int i = 0; i < _forms.Count; i++)
{
IForm frm = (IForm)_forms[i];
frm.OnRender(dc);
}
}
protected override void OnTouchDown(Microsoft.SPOT.Input.TouchEventArgs e)
{
_dl.AddForm(_controller, Colors.Red, 10, 10, 200, 98);
base.OnTouchDown(e);
}
protected override void OnTouchUp(Microsoft.SPOT.Input.TouchEventArgs e)
{
base.OnTouchUp(e);
}
}
interface IForm
{
Color background
{
get;
set;
}
int x
{
get;
set;
}
int y
{
get;
set;
}
int width
{
get;
set;
}
int height
{
get;
set;
}
void OnRender(DrawingContext dc);
}
[Serializable]
public class form : MarshalByRefObject, IForm
{
private Color _bkg;
private int _x;
private int _y;
private int _w;
private int _h;
public Color background
{
get { return _bkg; }
set { _bkg = value; }
}
public int x
{
get { return _x; }
set { _x = value; }
}
public int y
{
get { return _y; }
set { _y = value; }
}
public int width
{
get { return _w; }
set { _w = value; }
}
public int height
{
get { return _h; }
set { _h = value; }
}
public void OnRender(DrawingContext dc)
{
Brush bshBkg = new SolidColorBrush(_bkg);
dc.DrawRectangle(bshBkg, null, _x, _y, _w, _h);
}
}
public class DynamicLoading
{
/// <summary>
/// The interface for a standlone application
/// </summary>
interface IApplication
{
/// <summary>
/// A sample method to invoke
/// </summary>
/// <returns></returns>
void AddTestForm(Controller controller, Color color, int X, int Y, int Width, int Height);
}
/// <summary>
/// A class that can be loaded across applicaiton domains which
/// implements the IApplicaiton interface
/// </summary>
public class Application : MarshalByRefObject, IApplication
{
/// <summary>
/// we need a defautl consturctor to create an instance of this object
/// across an application domain
/// </summary>
public Application()
{
}
void IApplication.AddTestForm(Controller controller, Color color, int X, int Y, int Width, int Height)
{
Debug.Print("Current Domain: " + AppDomain.CurrentDomain.FriendlyName);
form frm = controller.addForm();
frm.background = color;
frm.x = X;
frm.y = Y;
frm.width = Width;
frm.height = Height;
}
}
private ArrayList _domains = new ArrayList();
private ArrayList _apps = new ArrayList();
/// <summary>
/// The executable entry point.
/// </summary>
public void AddForm(Controller controller, Color color, int X, int Y, int Width, int Height)
{
// create a new application domain
Debug.Print("Creating AppDomain");
AppDomain ad = AppDomain.CreateDomain("pyxis2.apps");
_domains.Add(ad);
// create an instance of the IApplication type
// please note that the following call will also load the assembly that contains that type
// which we pass as first parameter
Debug.Print("Creating App Launcher Instance...");
IApplication app;
try
{
app = (IApplication)ad.CreateInstanceAndUnwrap(typeof(IApplication).Assembly.FullName, typeof(Application).FullName);
}
catch (Exception e)
{
string strInner = e.InnerException.ToString();
string strStack = e.StackTrace.ToString();
Debug.Print("FAILED: " + e.Message + "\n" + strInner + strStack);
return;
}
_apps.Add(app);
Debug.Print("Launching App..");
try
{
//app.StartExecution(controller, path);
app.AddTestForm(controller, color, X, Y, Width, Height);
}
catch (Exception e)
{
string strInner = e.InnerException.ToString();
string strStack = e.StackTrace.ToString();
Debug.Print("FAILED: " + e.Message + "\n" + strInner + strStack);
return;
}
}
}
}