Saturday, November 24, 2007

Directly Invoking methods in Seperate AppDomains

You can directly execute methods from one app domain (calling app domain) to another (the target app domain) without having the calling app domain load the types that will also be loaded in the target domain.

You need one common class that is referenced in both app domains. This common class will simply store the name of the assembly, class, method and parameters of the method. The common class will be created in the main app domain and sent to the target app domain. This class is a MarshalByValue type and will be serialized HOWEVER it has one special property that extends MarshalByRef. We will get back to why that is important later.

Step #1: Build the Target App Domain

AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = @"C:\TEST";
System.AppDomain targetDomain= System.AppDomain.CreateDomain("Test_Domain", System.AppDomain.CurrentDomain.Evidence, setup);

The code above creates a new AppDomain. Once created it is ready to execute any class that it's Assembly probing has access to. Obviously the code above is running inside the primary AppDomain or DefaultDomain or some other AppDomain. The point is there are at least 2 AppDomains in this scenario.

Step #2: Create the "common" InvocationRequest object

InvocationRequest request = new Invocation.InvocationRequest();
request.AssemblyName = "TestLibrary";
request.ClassName = "TestLibrary.Test";
request.MethodName = "Kill";
request.Singleton = true;

This InvocationRequest class is nothing more than a bunch of string properties and a method that implements the CrossAppDomainDelegate method signature. To implement this delegate you only need a method of void MethodName(). Lemme explain a bit more, this is the most important piece to understand. Assume I implement the CrossAppDomainDelegate with a method named Invoke(). Remember, the primary AppDomain creates the InvocationRequest instance it then sends this instance to the target AppDomain thru the use of the DoCallBack() method.

public class InvocationRequest
{
... getters/setters ////

public void Invoke()
{
// load and invoke any code you like...
// This code will run in the Target AppDomain
object invocationTarget = AppDomain.CurrentDomain.CreateInstanceAndUnwrap(AssemblyName, ClassName);
Type type = invocationTarget.GetType();
System.Reflection.MethodInfo mi = type.GetMethod(methName);
object rtn_o = mi.Invoke(invocationTarget, Parameters.ToArray());
if (rtn_o != null)
{
this.Result.Value = rtnVal;
}
}
}

Step #3: Invoking inside the Target Domain:

targetDomain.DoCallBack( new CrossAppDomainDelegate( request.Invoke ));

This code is executed from the Main AppDomain (the Calling AppDomain). It will send the instance of the request object via Serialization to the other AppDomain. However, the Invoke() method will actually run in target domain context.

Step #4: Expose return values to the Calling AppDomain

The InvocationRequest class is serialized from the calling AppDomain to target AppDomain because it is a MBV (MarshalByValue) as are almost all objects. If we add a property to the InvocationRequest that extends MBR (MarshalByRef) then we can set it's value in the target domain and read it in the calling domain.

public class InvocationResult : MarshalByRefObject
{
private object _value;

public object Value
{
get { return _value; }
set { _value = value; }
}
}

If you added a property of type InvocationResult to the InvocationRequest class then you will now have the ability to share a common object amongst multiple AppDomains.

Wednesday, November 7, 2007

Just because you know C# or JAVA doesn't mean you know OO, seriously!

Ask a programmer what languages they know. You'll get responses like C#, Java, ASP, Powerbuilder etc... Then ask if they know OO, they'll say of course I do, I just told you I know C#, Java, ASP blah blah blah.

I've done so many interviews where the candidate rates themselves so high on these technologies but cannot answer any OO questions. For example, I am interviewing a C# candidate, this person rates himself as a 9 on a scale of 10. I'll ask him "what is an interface in the sense of OO" He'll respond its the GUI. I'll say, "no, I am referring to the OO interface, similar to a class." I hear crickets. This is not a unique experience. What do they teach at school? Oh, ask a programmer what boxing is... silence? Weird looks? I am always happy to find that 1 out of 10 candidate that actually knows these questions, it makes me feel normal and happy again.

So back to my rant, this is just the surface of the problem, we have thousands of programmers out there who are building systems, leading projects who absolutely do not know what they are doing! I am not a negative person, I actually LOVE teaching people how to write software but programmers are for some crazy reason more stubborn when they don't understand something. The less you know the tighter you hold on to your ignorance.

Classes

If a programmer knows how to construct a class and compile they feel very accomplished. They should, it's a great feeling learning a new language but don't get so full of yourself and stop the learning there. The most common mis-conception I see out there is if the software is built with classes then it is OO based. WRONG!. I guess what cheeses me off the most is that many programmers dont think that it is very important.. That is until they need to revamp it because it isn't scalable or easily adaptable. I admit I enjoy that moment but in the end it simply results in more work for everyone....