Someone please answer this question: Why does Microsoft mostly tend to make tools geared to dumb down software developers? Linq is a perfect example as well as Lambda, I mean they sell it and demo it under these perfect world scenarios that almost no one in the "real world" would have the luxury of having.
School labs and small start up businesses may be able to leverage these tools because they can't afford or don't have real software people and that's fine but in my experience systems built on these technologies (technologies that hide the complexity) are slow, inefficient and short lived. In the real world you have to deal with data coming from multiples sources, some you control some you don't. Ever try and fix a performance or data problem that is occurring due to code that you don't control? If you do figure it out and perform a work around all you've done is add to the layers of complexity that you don't own or control.
I think this is why most Java programmers despise Microsoft products and philosophies but I am a fan of both Java and C#. Love C# IDE's but love Java's philosophies which are mostly pragmatic and common sensible (mostly, EJB...not so much). It's been my experience that most very large enterprise systems (like GM, OnStar, BCBS, IBM, Oracle and on and on..) use Java because it's truly a decoupled platform that realizes that most large businesses do not have all their systems on the same version or even the same platform, Microsoft has always had the view (whether they admit it or not) that you will be operating from a Microsoft centric point-of-view.
Monday, June 21, 2010
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.
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....
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....
Subscribe to:
Posts (Atom)