Created
March 30, 2010 18:22
-
-
Save JohannesRudolph/349392 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using Library; | |
using System.Reflection; | |
using System.Runtime.Remoting.Proxies; | |
using System.Runtime.Remoting.Services; | |
using System.Runtime.Remoting.Messaging; | |
using System.Runtime.Remoting.Activation; | |
namespace Library | |
{ | |
internal interface IRunner | |
{ | |
void Execute(); | |
} | |
public sealed class AssemblyRunner : IRunner | |
{ | |
void IRunner.Execute() | |
{ | |
Console.WriteLine("executing"); | |
} | |
} | |
public class CompositeRunner | |
{ | |
private readonly Type runnerType; | |
public CompositeRunner(Type runnerType) | |
{ | |
this.runnerType = runnerType; | |
} | |
public void Execute() | |
{ | |
if (!typeof(IRunner).IsAssignableFrom(runnerType)) | |
throw new InvalidOperationException("invalid type"); | |
var runner = (IRunner)Activator.CreateInstance(runnerType); | |
Console.WriteLine("starting"); | |
runner.Execute(); | |
Console.WriteLine("done"); | |
} | |
} | |
} | |
namespace ConsoleApplication1 | |
{ | |
/// <summary> | |
/// Fakes the type of RunnerProxy. | |
/// </summary> | |
public class RunnerProxyType : TypeDelegator | |
{ | |
public static readonly Type runnerInterfaceType = typeof(AssemblyRunner).Assembly.GetType("Library.IRunner"); | |
private bool hasCheckedAssignableFrom = false; | |
/// <summary> | |
/// Initializes a new instance of the RunnerProxyType class. | |
/// </summary> | |
public RunnerProxyType() : base(runnerInterfaceType) | |
{ | |
} | |
/// <summary> | |
/// Returns IRunner on the first call and the RunnerProxyHook afterwards. | |
/// </summary> | |
public override Type UnderlyingSystemType | |
{ | |
get | |
{ | |
if (!hasCheckedAssignableFrom) | |
{ | |
hasCheckedAssignableFrom = true; | |
return runnerInterfaceType; | |
} | |
// The callee will try to instantiate this | |
return typeof(RunnerProxyCreationHook); | |
} | |
} | |
} | |
/// <summary> | |
/// Intercepts object creation to return a proxy. | |
/// </summary> | |
class ActivatorCreateInstanceHook : ProxyAttribute | |
{ | |
/// <summary> | |
/// Return a proxy to the callee. | |
/// </summary> | |
/// <param name="serverType"></param> | |
/// <returns></returns> | |
public override MarshalByRefObject CreateInstance(Type serverType) | |
{ | |
var proxy = new RunnerProxy(); | |
return (MarshalByRefObject)proxy.GetTransparentProxy(); | |
// after returning the proxy instance will receive a construction message | |
} | |
} | |
/// <summary> | |
/// Does nothing but providing a hook for object creation. | |
/// </summary> | |
[ActivatorCreateInstanceHook] | |
class RunnerProxyCreationHook : ContextBoundObject | |
{ | |
} | |
public class RunnerProxy : RealProxy | |
{ | |
public static readonly Type runnerInterfaceType = typeof(AssemblyRunner).Assembly.GetType("Library.IRunner"); | |
public RunnerProxy() | |
: base(runnerInterfaceType) | |
{ | |
} | |
public override IMessage Invoke(IMessage msg) | |
{ | |
IConstructionCallMessage cmsg = msg as IConstructionCallMessage; | |
if (cmsg != null) | |
{ | |
// return the proxy again | |
return EnterpriseServicesHelper.CreateConstructionReturnMessage(cmsg, (MarshalByRefObject)this.GetTransparentProxy()); | |
} | |
IMethodCallMessage mmsg = msg as IMethodCallMessage; | |
if (mmsg != null && mmsg.MethodName == "Execute") | |
{ | |
Console.WriteLine("before executing"); | |
AssemblyRunner r = new AssemblyRunner(); | |
runnerInterfaceType.GetMethod("Execute").Invoke(r, null); | |
Console.WriteLine("after executing"); | |
return new ReturnMessage(null, mmsg); | |
} | |
throw new NotSupportedException(); | |
} | |
} | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
CompositeRunner comprunner = new CompositeRunner(new RunnerProxyType()); | |
comprunner.Execute(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment